This commit is contained in:
FluorescentCIAAfricanAmerican
2020-04-22 12:56:21 -04:00
commit 3bf9df6b27
15370 changed files with 5489726 additions and 0 deletions

169
utils/hlmv/anorms.h Normal file
View File

@@ -0,0 +1,169 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
{-0.525731f, 0.000000f, 0.850651f},
{-0.442863f, 0.238856f, 0.864188f},
{-0.295242f, 0.000000f, 0.955423f},
{-0.309017f, 0.500000f, 0.809017f},
{-0.162460f, 0.262866f, 0.951056f},
{0.000000f, 0.000000f, 1.000000f},
{0.000000f, 0.850651f, 0.525731f},
{-0.147621f, 0.716567f, 0.681718f},
{0.147621f, 0.716567f, 0.681718f},
{0.000000f, 0.525731f, 0.850651f},
{0.309017f, 0.500000f, 0.809017f},
{0.525731f, 0.000000f, 0.850651f},
{0.295242f, 0.000000f, 0.955423f},
{0.442863f, 0.238856f, 0.864188f},
{0.162460f, 0.262866f, 0.951056f},
{-0.681718f, 0.147621f, 0.716567f},
{-0.809017f, 0.309017f, 0.500000f},
{-0.587785f, 0.425325f, 0.688191f},
{-0.850651f, 0.525731f, 0.000000f},
{-0.864188f, 0.442863f, 0.238856f},
{-0.716567f, 0.681718f, 0.147621f},
{-0.688191f, 0.587785f, 0.425325f},
{-0.500000f, 0.809017f, 0.309017f},
{-0.238856f, 0.864188f, 0.442863f},
{-0.425325f, 0.688191f, 0.587785f},
{-0.716567f, 0.681718f, -0.147621f},
{-0.500000f, 0.809017f, -0.309017f},
{-0.525731f, 0.850651f, 0.000000f},
{0.000000f, 0.850651f, -0.525731f},
{-0.238856f, 0.864188f, -0.442863f},
{0.000000f, 0.955423f, -0.295242f},
{-0.262866f, 0.951056f, -0.162460f},
{0.000000f, 1.000000f, 0.000000f},
{0.000000f, 0.955423f, 0.295242f},
{-0.262866f, 0.951056f, 0.162460f},
{0.238856f, 0.864188f, 0.442863f},
{0.262866f, 0.951056f, 0.162460f},
{0.500000f, 0.809017f, 0.309017f},
{0.238856f, 0.864188f, -0.442863f},
{0.262866f, 0.951056f, -0.162460f},
{0.500000f, 0.809017f, -0.309017f},
{0.850651f, 0.525731f, 0.000000f},
{0.716567f, 0.681718f, 0.147621f},
{0.716567f, 0.681718f, -0.147621f},
{0.525731f, 0.850651f, 0.000000f},
{0.425325f, 0.688191f, 0.587785f},
{0.864188f, 0.442863f, 0.238856f},
{0.688191f, 0.587785f, 0.425325f},
{0.809017f, 0.309017f, 0.500000f},
{0.681718f, 0.147621f, 0.716567f},
{0.587785f, 0.425325f, 0.688191f},
{0.955423f, 0.295242f, 0.000000f},
{1.000000f, 0.000000f, 0.000000f},
{0.951056f, 0.162460f, 0.262866f},
{0.850651f, -0.525731f, 0.000000f},
{0.955423f, -0.295242f, 0.000000f},
{0.864188f, -0.442863f, 0.238856f},
{0.951056f, -0.162460f, 0.262866f},
{0.809017f, -0.309017f, 0.500000f},
{0.681718f, -0.147621f, 0.716567f},
{0.850651f, 0.000000f, 0.525731f},
{0.864188f, 0.442863f, -0.238856f},
{0.809017f, 0.309017f, -0.500000f},
{0.951056f, 0.162460f, -0.262866f},
{0.525731f, 0.000000f, -0.850651f},
{0.681718f, 0.147621f, -0.716567f},
{0.681718f, -0.147621f, -0.716567f},
{0.850651f, 0.000000f, -0.525731f},
{0.809017f, -0.309017f, -0.500000f},
{0.864188f, -0.442863f, -0.238856f},
{0.951056f, -0.162460f, -0.262866f},
{0.147621f, 0.716567f, -0.681718f},
{0.309017f, 0.500000f, -0.809017f},
{0.425325f, 0.688191f, -0.587785f},
{0.442863f, 0.238856f, -0.864188f},
{0.587785f, 0.425325f, -0.688191f},
{0.688191f, 0.587785f, -0.425325f},
{-0.147621f, 0.716567f, -0.681718f},
{-0.309017f, 0.500000f, -0.809017f},
{0.000000f, 0.525731f, -0.850651f},
{-0.525731f, 0.000000f, -0.850651f},
{-0.442863f, 0.238856f, -0.864188f},
{-0.295242f, 0.000000f, -0.955423f},
{-0.162460f, 0.262866f, -0.951056f},
{0.000000f, 0.000000f, -1.000000f},
{0.295242f, 0.000000f, -0.955423f},
{0.162460f, 0.262866f, -0.951056f},
{-0.442863f, -0.238856f, -0.864188f},
{-0.309017f, -0.500000f, -0.809017f},
{-0.162460f, -0.262866f, -0.951056f},
{0.000000f, -0.850651f, -0.525731f},
{-0.147621f, -0.716567f, -0.681718f},
{0.147621f, -0.716567f, -0.681718f},
{0.000000f, -0.525731f, -0.850651f},
{0.309017f, -0.500000f, -0.809017f},
{0.442863f, -0.238856f, -0.864188f},
{0.162460f, -0.262866f, -0.951056f},
{0.238856f, -0.864188f, -0.442863f},
{0.500000f, -0.809017f, -0.309017f},
{0.425325f, -0.688191f, -0.587785f},
{0.716567f, -0.681718f, -0.147621f},
{0.688191f, -0.587785f, -0.425325f},
{0.587785f, -0.425325f, -0.688191f},
{0.000000f, -0.955423f, -0.295242f},
{0.000000f, -1.000000f, 0.000000f},
{0.262866f, -0.951056f, -0.162460f},
{0.000000f, -0.850651f, 0.525731f},
{0.000000f, -0.955423f, 0.295242f},
{0.238856f, -0.864188f, 0.442863f},
{0.262866f, -0.951056f, 0.162460f},
{0.500000f, -0.809017f, 0.309017f},
{0.716567f, -0.681718f, 0.147621f},
{0.525731f, -0.850651f, 0.000000f},
{-0.238856f, -0.864188f, -0.442863f},
{-0.500000f, -0.809017f, -0.309017f},
{-0.262866f, -0.951056f, -0.162460f},
{-0.850651f, -0.525731f, 0.000000f},
{-0.716567f, -0.681718f, -0.147621f},
{-0.716567f, -0.681718f, 0.147621f},
{-0.525731f, -0.850651f, 0.000000f},
{-0.500000f, -0.809017f, 0.309017f},
{-0.238856f, -0.864188f, 0.442863f},
{-0.262866f, -0.951056f, 0.162460f},
{-0.864188f, -0.442863f, 0.238856f},
{-0.809017f, -0.309017f, 0.500000f},
{-0.688191f, -0.587785f, 0.425325f},
{-0.681718f, -0.147621f, 0.716567f},
{-0.442863f, -0.238856f, 0.864188f},
{-0.587785f, -0.425325f, 0.688191f},
{-0.309017f, -0.500000f, 0.809017f},
{-0.147621f, -0.716567f, 0.681718f},
{-0.425325f, -0.688191f, 0.587785f},
{-0.162460f, -0.262866f, 0.951056f},
{0.442863f, -0.238856f, 0.864188f},
{0.162460f, -0.262866f, 0.951056f},
{0.309017f, -0.500000f, 0.809017f},
{0.147621f, -0.716567f, 0.681718f},
{0.000000f, -0.525731f, 0.850651f},
{0.425325f, -0.688191f, 0.587785f},
{0.587785f, -0.425325f, 0.688191f},
{0.688191f, -0.587785f, 0.425325f},
{-0.955423f, 0.295242f, 0.000000f},
{-0.951056f, 0.162460f, 0.262866f},
{-1.000000f, 0.000000f, 0.000000f},
{-0.850651f, 0.000000f, 0.525731f},
{-0.955423f, -0.295242f, 0.000000f},
{-0.951056f, -0.162460f, 0.262866f},
{-0.864188f, 0.442863f, -0.238856f},
{-0.951056f, 0.162460f, -0.262866f},
{-0.809017f, 0.309017f, -0.500000f},
{-0.864188f, -0.442863f, -0.238856f},
{-0.951056f, -0.162460f, -0.262866f},
{-0.809017f, -0.309017f, -0.500000f},
{-0.681718f, 0.147621f, -0.716567f},
{-0.681718f, -0.147621f, -0.716567f},
{-0.850651f, 0.000000f, -0.525731f},
{-0.688191f, 0.587785f, -0.425325f},
{-0.587785f, 0.425325f, -0.688191f},
{-0.425325f, 0.688191f, -0.587785f},
{-0.425325f, -0.688191f, -0.587785f},
{-0.587785f, -0.425325f, -0.688191f},
{-0.688191f, -0.587785f, -0.425325f},

View File

@@ -0,0 +1,349 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "attachments_window.h"
#include "ControlPanel.h"
#include "ViewerSettings.h"
#include "StudioModel.h"
#include "MatSysWin.h"
#define IDC_ATTACHMENT_LIST (IDC_ATTACHMENT_WINDOW_FIRST+0)
#define IDC_ATTACHMENT_LIST_BONES (IDC_ATTACHMENT_WINDOW_FIRST+1)
#define IDC_ATTACHMENT_TRANSLATION (IDC_ATTACHMENT_WINDOW_FIRST+2)
#define IDC_ATTACHMENT_ROTATION (IDC_ATTACHMENT_WINDOW_FIRST+3)
#define IDC_ATTACHMENT_QC_STRING (IDC_ATTACHMENT_WINDOW_FIRST+4)
CAttachmentsWindow::CAttachmentsWindow( ControlPanel* pParent ) : mxWindow( pParent, 0, 0, 0, 0 )
{
m_pControlPanel = pParent;
g_viewerSettings.m_iEditAttachment = -1;
}
void CAttachmentsWindow::Init( )
{
int left, top;
left = 5;
top = 0;
// Attachment selection list
new mxLabel( this, left + 3, top + 4, 60, 18, "Attachment" );
m_cAttachmentList = new mxListBox( this, left, top + 20, 260, 100, IDC_ATTACHMENT_LIST );
m_cAttachmentList->add ("None");
m_cAttachmentList->select (0);
mxToolTip::add (m_cAttachmentList, "Select an attachment to modify");
left = 280;
new mxLabel( this, left + 3, top + 4, 60, 18, "Attach To Bone" );
m_cBoneList = new mxListBox( this, left, top + 20, 260, 100, IDC_ATTACHMENT_LIST_BONES );
m_cBoneList->add ("None");
m_cBoneList->select( 0 );
mxToolTip::add( m_cBoneList, "Select a bone to attach to" );
left = 5;
top = 120;
new mxLabel( this, left + 3, top + 4, 60, 18, "Translation" );
m_cTranslation = new mxLineEdit2( this, left + 70, top, 90, 25, "10 20 30", IDC_ATTACHMENT_TRANSLATION );
left = 170;
top = 120;
new mxLabel( this, left + 3, top + 4, 60, 18, "Rotation" );
m_cRotation = new mxLineEdit2( this, left + 70, top, 90, 25, "0 90 180", IDC_ATTACHMENT_ROTATION );
top = 145;
left = 5;
new mxLabel( this, left, top, 60, 18, "QC String" );
m_cQCString = new mxLineEdit2( this, left + 70, top, 400, 25, "$attachment \"controlpanel0_ur\" \"Vgui\" -22 -15 4 rotate 0 0 0", IDC_ATTACHMENT_QC_STRING );
}
void CAttachmentsWindow::OnLoadModel()
{
int iPrevEdit = g_viewerSettings.m_iEditAttachment;
PopulateBoneList();
PopulateAttachmentsList();
if ( iPrevEdit >= 0 && iPrevEdit < m_cAttachmentList->getItemCount())
{
m_cAttachmentList->select( iPrevEdit + 1 );
}
g_viewerSettings.m_iEditAttachment = iPrevEdit;
UpdateStrings();
}
void CAttachmentsWindow::OnTabSelected()
{
// for now, keep selection
// g_viewerSettings.m_iEditAttachment = m_cAttachmentList->getSelectedIndex() - 1;
}
void CAttachmentsWindow::OnTabUnselected()
{
// for now, keep selection
// g_viewerSettings.m_iEditAttachment = -1;
}
void CAttachmentsWindow::PopulateAttachmentsList()
{
m_cAttachmentList->removeAll();
m_cAttachmentList->add( "(none)" );
if ( g_pStudioModel )
{
CStudioHdr* pHdr = g_pStudioModel->GetStudioHdr();
if (pHdr->GetNumAttachments())
{
for ( int i = 0; i < pHdr->GetNumAttachments(); i++ )
{
m_cAttachmentList->add ( pHdr->pAttachment(i).pszName() );
}
m_cAttachmentList->select (0);
OnSelChangeAttachmentList();
return;
}
}
m_cAttachmentList->select (0);
}
void CAttachmentsWindow::PopulateBoneList()
{
m_cBoneList->removeAll();
if ( g_pStudioModel )
{
CStudioHdr* pHdr = g_pStudioModel->GetStudioHdr();
if (pHdr->numbones())
{
for ( int i = 0; i < pHdr->numbones(); i++ )
{
m_cBoneList->add ( pHdr->pBone(i)->pszName() );
}
m_cBoneList->select (0);
return;
}
}
m_cBoneList->add( "None" );
m_cBoneList->select (0);
}
int CAttachmentsWindow::handleEvent (mxEvent *event)
{
MDLCACHE_CRITICAL_SECTION_( g_pMDLCache );
if ( !g_pStudioModel )
return 0;
CStudioHdr* pHdr = g_pStudioModel->GetStudioHdr();
switch( event->action )
{
case IDC_ATTACHMENT_LIST:
{
OnSelChangeAttachmentList();
}
break;
case IDC_ATTACHMENT_LIST_BONES:
{
int iAttachment = g_viewerSettings.m_iEditAttachment;
int iBone = m_cBoneList->getSelectedIndex();
if ( iAttachment >= 0 &&
iAttachment < pHdr->GetNumAttachments() &&
iBone >= 0 &&
iBone < pHdr->numbones() )
{
pHdr->SetAttachmentBone( iAttachment, iBone );
UpdateStrings();
}
}
break;
case IDC_ATTACHMENT_TRANSLATION:
{
int iAttachment = g_viewerSettings.m_iEditAttachment;
if ( iAttachment >= 0 &&
iAttachment < pHdr->GetNumAttachments() )
{
mstudioattachment_t &pAttachment = (mstudioattachment_t &)pHdr->pAttachment( iAttachment );
Vector vTrans( 0, 0, 0 );
char curText[512];
m_cTranslation->getText( curText, sizeof( curText ) );
sscanf( curText, "%f %f %f", &vTrans.x, &vTrans.y, &vTrans.z );
pAttachment.local[0][3] = vTrans.x;
pAttachment.local[1][3] = vTrans.y;
pAttachment.local[2][3] = vTrans.z;
UpdateStrings( true, false, false );
}
}
break;
case IDC_ATTACHMENT_ROTATION:
{
int iAttachment = g_viewerSettings.m_iEditAttachment;
if ( iAttachment >= 0 &&
iAttachment < pHdr->GetNumAttachments() )
{
mstudioattachment_t &pAttachment = (mstudioattachment_t &)pHdr->pAttachment( iAttachment );
QAngle vRotation( 0, 0, 0 );
char curText[512];
m_cRotation->getText( curText, sizeof( curText ) );
sscanf( curText, "%f %f %f", &vRotation.x, &vRotation.y, &vRotation.z );
Vector vTrans = GetCurrentTranslation();
AngleMatrix( vRotation, vTrans, pAttachment.local );
UpdateStrings( true, false, false );
}
}
break;
default:
return 0;
}
return 1;
}
void CAttachmentsWindow::OnSelChangeAttachmentList()
{
CStudioHdr *pStudioHdr = g_pStudioModel ? g_pStudioModel->GetStudioHdr() : NULL;
if ( !pStudioHdr )
return;
int iAttachment = m_cAttachmentList->getSelectedIndex() - 1;
if ( iAttachment >= 0 && iAttachment < pStudioHdr->GetNumAttachments() )
{
g_viewerSettings.m_iEditAttachment = iAttachment;
// Init the bone list index.
int iBone = g_pStudioModel->GetStudioHdr()->GetAttachmentBone( iAttachment );
m_cBoneList->select( iBone );
}
else
{
g_viewerSettings.m_iEditAttachment = -1;
}
UpdateStrings();
}
Vector CAttachmentsWindow::GetCurrentTranslation()
{
CStudioHdr *pStudioHdr = g_pStudioModel ? g_pStudioModel->GetStudioHdr() : NULL;
int iAttachment = m_cAttachmentList->getSelectedIndex() - 1;
if ( pStudioHdr && iAttachment >= 0 && iAttachment < pStudioHdr->GetNumAttachments() )
{
mstudioattachment_t &pAttachment = (mstudioattachment_t &)pStudioHdr->pAttachment( iAttachment );
return Vector( pAttachment.local[0][3],
pAttachment.local[1][3],
pAttachment.local[2][3] );
}
else
{
return vec3_origin;
}
}
Vector CAttachmentsWindow::GetCurrentRotation()
{
CStudioHdr *pStudioHdr = g_pStudioModel ? g_pStudioModel->GetStudioHdr() : NULL;
int iAttachment = m_cAttachmentList->getSelectedIndex() - 1;
if ( pStudioHdr && iAttachment >= 0 && iAttachment < pStudioHdr->GetNumAttachments() )
{
mstudioattachment_t &pAttachment = (mstudioattachment_t &)pStudioHdr->pAttachment( iAttachment );
float angles[3];
MatrixAngles( pAttachment.local, angles );
return Vector( angles[0], angles[1], angles[2] );
}
else
{
return vec3_origin;
}
}
void CAttachmentsWindow::UpdateStrings( bool bUpdateQC, bool bUpdateTranslation, bool bUpdateRotation )
{
char str[1024];
int iAttachment = -1;
CStudioHdr* pHdr = NULL;
if ( g_pStudioModel )
{
pHdr = g_pStudioModel->GetStudioHdr();
iAttachment = m_cAttachmentList->getSelectedIndex() - 1;
if ( iAttachment < 0 || iAttachment >= pHdr->GetNumAttachments() )
iAttachment = -1;
}
if ( iAttachment == -1 )
{
m_cTranslation->setText( "(none)" );
m_cRotation->setText( "(none)" );
m_cQCString->setText( "(none)" );
}
else
{
mstudioattachment_t &pAttachment = (mstudioattachment_t &)pHdr->pAttachment( iAttachment );
int iBone= pHdr->GetAttachmentBone( iAttachment );
Vector vTranslation = GetCurrentTranslation();
Vector vRotation = GetCurrentRotation();
if ( bUpdateQC )
{
sprintf( str, "$attachment \"%s\" \"%s\" %.2f %.2f %.2f rotate %.0f %.0f %.0f",
pAttachment.pszName(),
pHdr->pBone( iBone )->pszName(),
VectorExpand( vTranslation ),
VectorExpand( vRotation ) );
m_cQCString->setText( str );
}
if ( bUpdateTranslation )
{
sprintf( str, "%.2f %.2f %.2f", VectorExpand( vTranslation ) );
m_cTranslation->setText( str );
}
if ( bUpdateRotation )
{
sprintf( str, "%.0f %.0f %.0f", VectorExpand( vRotation ) );
m_cRotation->setText( str );
}
}
}

View File

@@ -0,0 +1,63 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef ATTACHMENTS_WINDOW_H
#define ATTACHMENTS_WINDOW_H
#ifdef _WIN32
#pragma once
#endif
#ifndef INCLUDED_MXWINDOW
#include <mxtk/mxWindow.h>
#endif
#include <mxtk/mx.h>
#include "mxLineEdit2.h"
#include "mathlib/vector.h"
class ControlPanel;
class CAttachmentsWindow : public mxWindow
{
public:
CAttachmentsWindow( ControlPanel* pParent );
void Init( );
void OnLoadModel();
void OnTabSelected();
void OnTabUnselected();
virtual int handleEvent( mxEvent *event );
private:
void OnSelChangeAttachmentList();
void PopulateAttachmentsList();
void PopulateBoneList();
void UpdateStrings( bool bUpdateQC=true, bool bUpdateTranslation=true, bool bUpdateRotation=true );
Vector GetCurrentTranslation();
Vector GetCurrentRotation();
private:
ControlPanel *m_pControlPanel;
mxListBox *m_cAttachmentList;
mxListBox *m_cBoneList;
mxLineEdit2 *m_cTranslation;
mxLineEdit2 *m_cRotation;
mxLineEdit2 *m_cQCString;
};
#endif // ATTACHMENTS_WINDOW_H

3989
utils/hlmv/controlpanel.cpp Normal file

File diff suppressed because it is too large Load Diff

480
utils/hlmv/controlpanel.h Normal file
View File

@@ -0,0 +1,480 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
//
// Half-Life Model Viewer (c) 1999 by Mete Ciragan
//
// file: ControlPanel.h
// last modified: May 29 programs and associated files contained in this
// distribution were developed by Mete Ciragan. The programs
// are not in the public domain, but they are freely
// distributable without licensing fees. These programs are
// provided without guarantee or warrantee expressed or
// implied.
//
// version: 1.2
//
// email: mete@swissquake.ch
// web: http://www.swissquake.ch/chumbalum-soft/
//
#ifndef INCLUDED_CONTROLPANEL
#define INCLUDED_CONTROLPANEL
#ifndef INCLUDED_MXWINDOW
#include <mxtk/mxWindow.h>
#endif
#define IDC_TAB 1901
#define IDC_RENDERMODE 2001
#define IDC_GROUND 2003
#define IDC_MOVEMENT 2004
#define IDC_BACKGROUND 2005
#define IDC_HITBOXES 2006
#define IDC_BONES 2007
#define IDC_ATTACHMENTS 2008
#define IDC_PHYSICSMODEL 2009
#define IDC_PHYSICSHIGHLIGHT 2010
#define IDC_LODCHOICE 2011
#define IDC_AUTOLOD 2012
#define IDC_LODSWITCH 2013
#define IDC_SOFTWARESKIN 2014
#define IDC_OVERBRIGHT2 2015
#define IDC_RENDER_FOV 2016
#define IDC_SEQUENCEBOXES 2017
#define IDC_RUNIK 2018
#define IDC_HEADTURN 2019
#define IDC_NORMALS 2020
#define IDC_TANGENTFRAME 2021
#define IDC_NORMALMAP 2022
#define IDC_SPECULAR 2023
#define IDC_SHADOW 2024
#define IDC_ILLUMPOSITION 2025
#define IDC_OVERLAY_WIREFRAME 2026
#define IDC_PLAYSOUNDS 2027
#define IDC_MESSAGES 2028
#define IDC_SHADERS 2029
//#define IDC_PARALLAXMAP 2030
#define IDC_SHOWORIGINAXIS 2029
#define IDC_ORIGINAXISLENGTH 2030
#define MAX_SEQUENCES 5
#define IDC_SEQUENCE0 3000
#define IDC_SEQUENCE1 3001
#define IDC_SEQUENCE2 3002
#define IDC_SEQUENCE3 3003
#define IDC_SEQUENCE4 3004
#define IDC_SEQUENCESCALE0 3005
#define IDC_SEQUENCESCALE1 3006
#define IDC_SEQUENCESCALE2 3007
#define IDC_SEQUENCESCALE3 3008
#define IDC_SEQUENCESCALE4 3009
#define IDC_FRAMESELECTION0 3010
#define IDC_FRAMESELECTION1 3011
#define IDC_FRAMESELECTION2 3012
#define IDC_FRAMESELECTION3 3013
#define IDC_FRAMESELECTION4 3014
#define NUM_POSEPARAMETERS 8
#define IDC_POSEPARAMETER_SCALE 3100
#define IDC_POSEPARAMETER 3120
#define IDC_POSEPARAMETER_VALUE 3140
#define IDC_SPEEDSCALE 3201
#define IDC_FORCEFRAME 3202
#define IDC_BLENDSEQUENCECHANGES 3203
#define IDC_BLENDNOW 3204
#define IDC_BLENDTIME 3205
#define IDC_ACTIVITY_MODIFIERS 3206
#define IDC_ANIMATEWEAPONS 3207
#define IDC_BODYPART 4001
#define IDC_SUBMODEL 4002
#define IDC_CONTROLLER 4003
#define IDC_CONTROLLERVALUE 4004
#define IDC_SKINS 4005
#define IDC_MATERIALS 4006
#define IDC_BONE_BONELIST 5000
#define IDC_BONE_GENERATEQC 5001
#define IDC_BONE_HIGHLIGHT_BONE 5002
#define IDC_BONE_HITBOXLIST 5003
#define IDC_BONE_SURFACEPROP 5004
#define IDC_BONE_HIGHLIGHT_HITBOX 5005
#define IDC_BONE_ADD_HITBOX 5006
#define IDC_BONE_DELETE_HITBOX 5007
#define IDC_BONE_APPLY_TO_CHILDREN 5008
#define IDC_BONE_SHOW_DEFAULT_POSE 5009
#define IDC_BONE_HITBOX_ORIGINX 5010
#define IDC_BONE_HITBOX_ORIGINY 5011
#define IDC_BONE_HITBOX_ORIGINZ 5012
#define IDC_BONE_HITBOX_SIZEX 5013
#define IDC_BONE_HITBOX_SIZEY 5014
#define IDC_BONE_HITBOX_SIZEZ 5015
#define IDC_BONE_HITBOX_GROUP 5016
#define IDC_BONE_UPDATE_HITBOX 5017
#define IDC_BONE_USE_AUTOGENERATED_HITBOXES 5018
#define IDC_BONE_HITBOXSET 5019
#define IDC_BONE_HITBOXADDSET 5020
#define IDC_BONE_HITBOXDELETESET 5021
#define IDC_BONE_HITBOXSETNAME 5022
#define IDC_BONE_HITBOXSETNAME_EDIT 5023
// This range is reserved for the attachment window.
#define IDC_ATTACHMENT_WINDOW_FIRST 5024
#define IDC_ATTACHMENT_WINDOW_LAST 5100
#define IDC_BONE_HITBOX_NAME 5101
#define IDC_BONE_SAVE_HITBOXES 5102
#define IDC_BONE_LOAD_HITBOXES 5103
#define IDC_FLEX 7001
#define IDC_FLEXDEFAULTS 7002
#define IDC_FLEXRANDOM 7003
#define IDC_FLEXZERO 7004
#define IDC_FLEXONE 7005
#define IDC_FLEXSCALE 7101
#define NUM_FLEX_SLIDERS 48
#define IDC_PHYS_FIRST 7501
#define IDC_PHYS_BONE 7501
#define IDC_PHYS_CON_LINK_LIMITS 7502
#define IDC_PHYS_MATERIAL 7503
#define IDC_PHYS_CON_MIN 7504
#define IDC_PHYS_CON_MAX 7505
#define IDC_PHYS_CON_TEST 7506
#define IDC_PHYS_P_MASSBIAS 7507
#define IDC_PHYS_CON_FRICTION 7508
//#define IDC_PHYS_P_ELASTICITY 7509
#define IDC_PHYS_P_INERTIA 7510
#define IDC_PHYS_P_DAMPING 7511
#define IDC_PHYS_P_ROT_DAMPING 7512
#define IDC_PHYS_MASS 7513
#define IDC_PHYS_QCFILE 7514
#define IDC_PHYS_CON_AXIS_X 7515
#define IDC_PHYS_CON_AXIS_Y 7516
#define IDC_PHYS_CON_AXIS_Z 7517
#define IDC_PHYS_CON_TYPE_FREE 7518
#define IDC_PHYS_CON_TYPE_FIXED 7519
#define IDC_PHYS_CON_TYPE_LIMIT 7520
#define IDC_PHYS_LAST 7599
#define MAX_ANIMS 4
#define IDC_ANIMX 8020 // through 8023 ( MAX_ANIMS )
#define IDC_ANIMY 8030 // through 8033 ( MAX_ANIMS )
#define IDC_IKRULE_CHAIN 9000
#define IDC_IKRULE_CHOICE 9001
#define IDC_IKRULE_TOUCH 9002
#define IDC_IKRULE_ATTACHMENT 9003
#define IDC_IKRULE_RANGE_TOGGLE 9004
#define IDC_IKRULE_RANGE_START 9005
#define IDC_IKRULE_RANGE_PEAK 9006
#define IDC_IKRULE_RANGE_TAIL 9007
#define IDC_IKRULE_RANGE_END 9008
#define IDC_IKRULE_RANGE_START_NOW 9009
#define IDC_IKRULE_RANGE_PEAK_NOW 9010
#define IDC_IKRULE_RANGE_TAIL_NOW 9011
#define IDC_IKRULE_RANGE_END_NOW 9012
#define IDC_IKRULE_CONTACT_TOGGLE 9013
#define IDC_IKRULE_CONTACT_FRAME_NOW 9014
#define IDC_IKRULE_CONTACT_FRAME 9015
#define IDC_IKRULE_USING 9016
#define IDC_IKRULE_QC_STRING 9017
#define IDC_EVENT_SOUND_FRAME_NOW 6000
#define IDC_EVENT_SOUND_FRAME 6001
#define IDC_EVENT_SOUND_NAME 6002
#define IDC_EVENT_QC_STRING 6003
class mxTab;
class mxChoice;
class mxCheckBox;
class mxSlider;
class mxLineEdit;
class mxLineEdit2;
class mxLabel;
class mxListBox;
class mxButton;
class mxRadioButton;
class MatSysWindow;
class TextureWindow;
class CBoneControlWindow;
class CAttachmentsWindow;
class CStudioHdr;
// Return codes from loadModel.
enum LoadModelResult_t
{
LoadModel_Success = 0,
LoadModel_LoadFail,
LoadModel_NoModel,
LoadModel_PostLoadFail,
};
class ControlPanel : public mxWindow
{
mxWindow *wRender;
mxTab *tab;
mxChoice *cRenderMode;
mxChoice *cHighlightBone;
mxCheckBox *cbGround;
mxCheckBox *cbHitBoxes;
mxCheckBox *cbSequenceBoxes;
mxCheckBox *cbShadow;
mxCheckBox *cbMovement;
mxCheckBox *cbBackground;
mxCheckBox *cbSoftwareSkin;
mxCheckBox *cbOverbright2;
mxCheckBox *cbAttachments;
mxCheckBox *cbBones;
mxCheckBox *cbNormals;
mxCheckBox *cbNormalMap;
// mxCheckBox *cbParallaxMap;
mxCheckBox *cbTangentFrame;
mxCheckBox *cbOverlayWireframe;
mxCheckBox *cbSpecular;
mxCheckBox *cbRunIK;
mxCheckBox *cbEnableHead;
mxCheckBox *cbIllumPosition;
mxCheckBox *cbPlaySounds;
mxCheckBox *cbShowOriginAxis;
mxSlider *leOriginAxisLength;
mxChoice *cLODChoice;
mxCheckBox *cbAutoLOD;
mxLineEdit *leLODSwitch;
mxLabel *lLODMetric;
mxChoice *cSequence[MAX_SEQUENCES];
mxSlider *slSequence[MAX_SEQUENCES];
int *iSelectionToSequence; // selection to sequence
int *iSequenceToSelection; // sequence to selection
mxLabel *laGroundSpeed;
mxSlider *slSpeedScale;
mxLabel *laFPS;
mxLabel *laBlendAmount;
mxChoice *cPoseParameter[NUM_POSEPARAMETERS];
mxSlider *slPoseParameter[NUM_POSEPARAMETERS];
mxLineEdit *lePoseParameter[NUM_POSEPARAMETERS];
mxLineEdit *leFOV;
mxSlider *slBlendTime;
mxLabel *laBlendTime;
mxChoice *cActivityModifiers;
mxSlider *slForceFrame;
mxLabel *lForcedFrame;
mxRadioButton *rbFrameSelection[MAX_SEQUENCES];
mxChoice *cBodypart, *cController, *cSubmodel;
mxSlider *slController;
mxChoice *cSkin;
mxChoice *cMaterials;
mxLabel *lModelInfo1, *lModelInfo2, *lModelInfo3, *lModelInfo4, *lModelInfo5;
//mxChoice *cTextures;
//mxCheckBox *cbChrome;
//mxLabel *lTexSize;
//mxLineEdit *leWidth, *leHeight;
mxLineEdit *leMeshScale, *leBoneScale;
MatSysWindow *d_MatSysWindow;
TextureWindow *d_textureWindow;
mxChoice *cFlex[NUM_FLEX_SLIDERS];
mxSlider *slFlexScale[NUM_FLEX_SLIDERS];
mxChoice *cPhysicsBone;
mxRadioButton *rbConstraintAxis[3];
mxSlider *slPhysicsFriction;
mxLabel *lPhysicsFriction;
mxSlider *slPhysicsConMin;
mxLabel *lPhysicsConMin;
mxCheckBox *cbLinked; // links min/max sliders
mxSlider *slPhysicsConMax;
mxLabel *lPhysicsConMax;
mxSlider *slPhysicsConTest;
mxLineEdit *leMass;
mxSlider *slPhysicsParamMassBias;
mxLabel *lPhysicsParamMassBias;
mxSlider *slPhysicsParamFriction;
mxLabel *lPhysicsParamFriction;
mxSlider *slPhysicsParamElasticity;
mxLabel *lPhysicsParamElasticity;
mxSlider *slPhysicsParamInertia;
mxLabel *lPhysicsParamInertia;
mxSlider *slPhysicsParamDamping;
mxLabel *lPhysicsParamDamping;
mxSlider *slPhysicsParamRotDamping;
mxLabel *lPhysicsParamRotDamping;
mxLabel *lPhysicsMaterial;
mxChoice *cIKChain;
mxChoice *cIKType;
mxLabel *lIKTouch;
mxChoice *cIKTouch;
mxLabel *lIKAttachment;
mxLineEdit *leIKAttachment;
mxCheckBox *cbIKRangeToggle;
mxLineEdit2 *leIKRangeStart;
mxLineEdit2 *leIKRangePeak;
mxLineEdit2 *leIKRangeTail;
mxLineEdit2 *leIKRangeEnd;
mxCheckBox *cbIKContactToggle;
mxLineEdit2 *leIKContactFrame;
mxChoice *cIKUsing;
mxLineEdit2 *leIKQCString;
mxLineEdit2 *leEventSoundFrame;
mxListBox *lbEventSoundName;
mxLineEdit2 *leEventQCString;
CBoneControlWindow* m_pBoneWindow;
CAttachmentsWindow* m_pAttachmentsWindow;
mxListBox *cMessageList;
mxListBox *cShaderUsed;
public:
// CREATORS
ControlPanel (mxWindow *parent);
virtual ~ControlPanel ();
virtual void OnDelete();
// MANIPULATORS
int handleEvent (mxEvent *event);
int handlePhysicsEvent( mxEvent *event );
void UpdateConstraintSliders( int clamp );
void setupPhysics( void );
void setupPhysicsBone( int boneIndex );
void setupPhysicsAxis( int boneIndex, int axis );
int getPhysicsAxis( void );
void setPhysicsAxis( int axisIndex );
void writePhysicsData( void );
void handlePhysicsKey( mxEvent *event );
// void readPhysicsMaterials( mxChoice *pList );
void dumpModelInfo ();
LoadModelResult_t loadModel(const char *filename);
LoadModelResult_t loadModel(const char *filename, int slot );
void OnLoadModel( void );
void resetControlPanel( void );
void setRenderMode (int mode);
void setShowGround (bool b);
void setShowMovement (bool b);
void setShowBackground (bool b);
void setShowNormals (bool b);
void setShowTangentFrame (bool b);
void setOverlayWireframe (bool b);
void setShowShadow (bool b);
void setShowHitBoxes (bool b);
void setShowBones (bool b);
void setShowAttachments (bool b);
void setHighlightBone( int index );
void setLOD( int index, bool setLODchoice, bool force );
void setAutoLOD( bool b );
void setSoftwareSkin( bool b );
void setOverbright( bool b );
void setLODMetric( float metric );
void setPolycount( int polycount );
void setModelInfo( int nVertCount, int nIndexCount, int nTriCount );
void setTransparent( bool isTransparent );
void updatePoseParameters( void );
void setFOV( float fov );
void setPlaySounds( bool b );
void setShowOriginAxis( bool b );
void setOriginAxisLength( float originAxisLength );
void initSequenceChoices();
void setSequence( int index );
void showActivityModifiers( int sequence );
void updateGroundSpeed( void );
void setOverlaySequence(int num, int index, float weight);
void updateTransitionAmount();
void startBlending( void );
void setSpeedScale ( float scale );
void updateSpeedScale( void );
void setBlend(int index, float value );
int getFrameSelection( void );
void setFrame( float frame );
void updateFrameSelection( void );
void updateFrameSlider( void );
void initBodypartChoices();
void setBodypart (int index);
void setSubmodel (int index);
void initBoneControllers ();
void setBoneController (int index);
void setBoneControllerValue (int index, float value);
void initSkinChoices();
void initMaterialChoices();
void setModelInfo ();
void initPhysicsBones();
void initLODs();
void centerView ();
void UpdateMaterialList ();
void viewmodelView();
void fullscreen ();
void setMatSysWindow (MatSysWindow *window) { d_MatSysWindow = window; }
void ConvertFlexData();
void initFlexes ();
void connectFlexes( CStudioHdr* hdr );
int GetCurrentHitboxSet( void );
void BuildIKRuleQCString();
void UpdateIKRuleWindow();
void BuildEventQCString();
void CreateSortedSequenceList( CStudioHdr* hdr, int *pSequence );
void SetFrameSlider( float flFrame );
void UnloadAllMergedModels();
public:
// Sets up the main tabs
void SetupRenderWindow( mxTab* pTab );
void SetupSequenceWindow( mxTab* pTab );
void SetupBoneControlWindow( mxTab* pTab );
void SetupBodyWindow( mxTab* pTab );
void SetupFlexWindow( mxTab* pTab );
void SetupPhysicsWindow( mxTab* pTab );
void SetupAttachmentsWindow( mxTab *pTab );
void SetupIKRuleWindow( mxTab *pTab );
void SetupEventWindow( mxTab *pTab );
bool m_bVMTInfoLoaded;
};
extern ControlPanel *g_ControlPanel;
#endif // INCLUDED_CONTROLPANEL

View File

@@ -0,0 +1,761 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#include "istudiorender.h"
#include "materialsystem/imesh.h"
#include "mathlib/mathlib.h"
#include "matsyswin.h"
#include "viewersettings.h"
#include "materialsystem/imaterialvar.h"
extern IMaterialSystem *g_pMaterialSystem;
#define NORMAL_LENGTH .5f
#define NORMAL_OFFSET_FROM_MESH 0.1f
int DebugDrawModel( IStudioRender *pStudioRender, DrawModelInfo_t& info,
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
{
// Make static so that we aren't reallocating everything all the time.
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
static GetTriangles_Output_t tris;
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
CMeshBuilder meshBuilder;
int batchID;
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
{
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
pRenderContext->Bind( materialBatch.m_pMaterial );
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(),
materialBatch.m_TriListIndices.Count() );
int vertID;
// Send the vertices down to the hardware.
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
{
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
const Vector &pos = vert.m_Position;
const Vector &normal = vert.m_Normal;
const Vector4D &tangentS = vert.m_TangentS;
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
int k;
for( k = 0; k < vert.m_NumBones; k++ )
{
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
Vector tmp;
VectorTransform( pos, poseToWorld, tmp );
skinnedPos += vert.m_BoneWeight[k] * tmp;
VectorRotate( normal, poseToWorld, tmp );
skinnedNormal += vert.m_BoneWeight[k] * tmp;
VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
}
meshBuilder.Position3fv( &skinnedPos.x );
meshBuilder.Normal3fv( &skinnedNormal.x );
meshBuilder.TexCoord2fv( 0, &vert.m_TexCoord.x );
meshBuilder.UserData( &skinnedTangentS.x );
meshBuilder.AdvanceVertex();
}
int i;
// Set the indices down to the hardware.
// Each triplet of indices is a triangle.
for( i = 0; i < materialBatch.m_TriListIndices.Count(); i++ )
{
meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
}
meshBuilder.End();
pBuildMesh->Draw();
}
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PopMatrix();
return 0;
}
int DebugDrawModelNormals( IStudioRender *pStudioRender, DrawModelInfo_t& info,
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
{
// Make static so that we aren't reallocating everything all the time.
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
static GetTriangles_Output_t tris;
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
int batchID;
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
{
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
CMeshBuilder meshBuilder;
pRenderContext->Bind( g_materialVertexColor );
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh();
meshBuilder.Begin( pBuildMesh, MATERIAL_LINES, materialBatch.m_Verts.Count() );
int vertID;
// Send the vertices down to the hardware.
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
{
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
const Vector &pos = vert.m_Position;
const Vector &normal = vert.m_Normal;
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
int k;
for( k = 0; k < vert.m_NumBones; k++ )
{
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
Vector tmp;
VectorTransform( pos, poseToWorld, tmp );
skinnedPos += vert.m_BoneWeight[k] * tmp;
VectorRotate( normal, poseToWorld, tmp );
skinnedNormal += vert.m_BoneWeight[k] * tmp;
}
// skinnedPos += skinnedNormal * NORMAL_OFFSET_FROM_MESH;
meshBuilder.Position3fv( &skinnedPos.x );
meshBuilder.Color3f( 0.0f, 0.0f, 1.0f );
meshBuilder.AdvanceVertex();
skinnedPos += skinnedNormal * NORMAL_LENGTH;
meshBuilder.Position3fv( &skinnedPos.x );
meshBuilder.Color3f( 0.0f, 0.0f, 1.0f );
meshBuilder.AdvanceVertex();
}
meshBuilder.End();
pBuildMesh->Draw();
}
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PopMatrix();
return 0;
}
int DebugDrawModelTangentS( IStudioRender *pStudioRender, DrawModelInfo_t& info,
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
{
// Make static so that we aren't reallocating everything all the time.
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
static GetTriangles_Output_t tris;
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
int batchID;
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
{
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
CMeshBuilder meshBuilder;
pRenderContext->Bind( g_materialVertexColor );
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh();
meshBuilder.Begin( pBuildMesh, MATERIAL_LINES, materialBatch.m_Verts.Count() );
int vertID;
// Send the vertices down to the hardware.
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
{
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
const Vector &pos = vert.m_Position;
const Vector &normal = vert.m_Normal;
const Vector4D &tangentS = vert.m_TangentS;
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
int k;
for( k = 0; k < vert.m_NumBones; k++ )
{
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
Vector tmp;
VectorTransform( pos, poseToWorld, tmp );
skinnedPos += vert.m_BoneWeight[k] * tmp;
VectorRotate( normal, poseToWorld, tmp );
skinnedNormal += vert.m_BoneWeight[k] * tmp;
VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
}
// skinnedPos += skinnedNormal * NORMAL_OFFSET_FROM_MESH;
meshBuilder.Position3fv( &skinnedPos.x );
meshBuilder.Color3f( 1.0f, 0.0f, 0.0f );
meshBuilder.AdvanceVertex();
skinnedPos += skinnedTangentS.AsVector3D() * NORMAL_LENGTH;
meshBuilder.Position3fv( &skinnedPos.x );
meshBuilder.Color3f( 1.0f, 0.0f, 0.0f );
meshBuilder.AdvanceVertex();
}
meshBuilder.End();
pBuildMesh->Draw();
}
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PopMatrix();
return 0;
}
int DebugDrawModelTangentT( IStudioRender *pStudioRender, DrawModelInfo_t& info,
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
{
// Make static so that we aren't reallocating everything all the time.
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
static GetTriangles_Output_t tris;
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
int batchID;
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
{
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
CMeshBuilder meshBuilder;
pRenderContext->Bind( g_materialVertexColor );
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh();
meshBuilder.Begin( pBuildMesh, MATERIAL_LINES, materialBatch.m_Verts.Count() );
int vertID;
// Send the vertices down to the hardware.
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
{
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
const Vector &pos = vert.m_Position;
const Vector &normal = vert.m_Normal;
const Vector4D &tangentS = vert.m_TangentS;
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
int k;
for( k = 0; k < vert.m_NumBones; k++ )
{
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
Vector tmp;
VectorTransform( pos, poseToWorld, tmp );
skinnedPos += vert.m_BoneWeight[k] * tmp;
VectorRotate( normal, poseToWorld, tmp );
skinnedNormal += vert.m_BoneWeight[k] * tmp;
VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
}
Vector skinnedTangentT = CrossProduct( skinnedNormal, skinnedTangentS.AsVector3D() ) * skinnedTangentS.w;
// skinnedPos += skinnedNormal * NORMAL_OFFSET_FROM_MESH;
meshBuilder.Position3fv( &skinnedPos.x );
meshBuilder.Color3f( 0.0f, 1.0f, 0.0f );
meshBuilder.AdvanceVertex();
skinnedPos += skinnedTangentT * NORMAL_LENGTH;
meshBuilder.Position3fv( &skinnedPos.x );
meshBuilder.Color3f( 0.0f, 1.0f, 0.0f );
meshBuilder.AdvanceVertex();
}
meshBuilder.End();
pBuildMesh->Draw();
}
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PopMatrix();
return 0;
}
int DebugDrawModelBadVerts( IStudioRender *pStudioRender, DrawModelInfo_t& info,
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
{
// Make static so that we aren't reallocating everything all the time.
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
static GetTriangles_Output_t tris;
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
CMeshBuilder meshBuilder;
int batchID;
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
{
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
pRenderContext->Bind( g_materialVertexColor );
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(),
materialBatch.m_TriListIndices.Count() );
int vertID;
// Send the vertices down to the hardware.
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
{
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
const Vector &pos = vert.m_Position;
const Vector &normal = vert.m_Normal;
const Vector4D &tangentS = vert.m_TangentS;
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
int k;
for( k = 0; k < vert.m_NumBones; k++ )
{
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
Vector tmp;
VectorTransform( pos, poseToWorld, tmp );
skinnedPos += vert.m_BoneWeight[k] * tmp;
VectorRotate( normal, poseToWorld, tmp );
skinnedNormal += vert.m_BoneWeight[k] * tmp;
VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
}
meshBuilder.Position3fv( &skinnedPos.x );
meshBuilder.Normal3fv( &skinnedNormal.x );
meshBuilder.TexCoord2fv( 0, &vert.m_TexCoord.x );
meshBuilder.UserData( &skinnedTangentS.x );
Vector color( 0.0f, 0.0f, 0.0f );
float len;
// check the length of the tangent S vector.
len = tangentS.AsVector3D().Length();
if( len < .9f || len > 1.1f )
{
color.Init( 1.0f, 0.0f, 0.0f );
}
// check the length of the normal.
len = normal.Length();
if( len < .9f || len > 1.1f )
{
color.Init( 1.0f, 0.0f, 0.0f );
}
// check the dot of tangent s and normal
float dot = DotProduct( tangentS.AsVector3D(), normal );
if( dot > .95 || dot < -.95 )
{
color.Init( 1.0f, 0.0f, 0.0f );
}
meshBuilder.Color3fv( color.Base() );
meshBuilder.AdvanceVertex();
}
int i;
// Set the indices down to the hardware.
// Each triplet of indices is a triangle.
for( i = 0; i < materialBatch.m_TriListIndices.Count(); i++ )
{
meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
}
meshBuilder.End();
pBuildMesh->Draw();
}
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PopMatrix();
return 0;
}
int DebugDrawModelWireframe( IStudioRender *pStudioRender, DrawModelInfo_t& info,
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, const Vector &color, int flags )
{
// Make static so that we aren't reallocating everything all the time.
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
static GetTriangles_Output_t tris;
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
CMeshBuilder meshBuilder;
int batchID;
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
{
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
pRenderContext->Bind( g_materialWireframeVertexColor );
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(),
materialBatch.m_TriListIndices.Count() );
int vertID;
// Send the vertices down to the hardware.
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
{
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
const Vector &pos = vert.m_Position;
const Vector &normal = vert.m_Normal;
const Vector4D &tangentS = vert.m_TangentS;
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
int k;
for( k = 0; k < vert.m_NumBones; k++ )
{
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
Vector tmp;
VectorTransform( pos, poseToWorld, tmp );
skinnedPos += vert.m_BoneWeight[k] * tmp;
VectorRotate( normal, poseToWorld, tmp );
skinnedNormal += vert.m_BoneWeight[k] * tmp;
VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
}
meshBuilder.Position3fv( &skinnedPos.x );
meshBuilder.Normal3fv( &skinnedNormal.x );
meshBuilder.TexCoord2fv( 0, &vert.m_TexCoord.x );
meshBuilder.UserData( &skinnedTangentS.x );
meshBuilder.Color3fv( color.Base() );
meshBuilder.AdvanceVertex();
}
int i;
// Set the indices down to the hardware.
// Each triplet of indices is a triangle.
for( i = 0; i < materialBatch.m_TriListIndices.Count(); i++ )
{
meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
}
meshBuilder.End();
pBuildMesh->Draw();
}
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PopMatrix();
return 0;
}
int DebugDrawModelBoneWeights( IStudioRender *pStudioRender, DrawModelInfo_t& info,
matrix3x4_t *pBoneToWorld, const Vector &modelOrigin, int flags )
{
// Make static so that we aren't reallocating everything all the time.
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
static GetTriangles_Output_t tris;
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
CMeshBuilder meshBuilder;
int batchID;
for( batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
{
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
pRenderContext->Bind( g_materialVertexColor );
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(),
materialBatch.m_TriListIndices.Count() );
int vertID;
// Send the vertices down to the hardware.
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
{
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
const Vector &pos = vert.m_Position;
const Vector &normal = vert.m_Normal;
const Vector4D &tangentS = vert.m_TangentS;
Vector skinnedPos( 0.0f, 0.0f, 0.0f );
Vector skinnedNormal( 0.0f, 0.0f, 0.0f );
Vector4D skinnedTangentS( 0.0f, 0.0f, 0.0f, vert.m_TangentS[3] );
int k;
for( k = 0; k < vert.m_NumBones; k++ )
{
const matrix3x4_t &poseToWorld = tris.m_PoseToWorld[ vert.m_BoneIndex[k] ];
Vector tmp;
VectorTransform( pos, poseToWorld, tmp );
skinnedPos += vert.m_BoneWeight[k] * tmp;
VectorRotate( normal, poseToWorld, tmp );
skinnedNormal += vert.m_BoneWeight[k] * tmp;
VectorRotate( tangentS.AsVector3D(), poseToWorld, tmp );
skinnedTangentS.AsVector3D() += vert.m_BoneWeight[k] * tmp;
}
meshBuilder.Position3fv( &skinnedPos.x );
meshBuilder.Normal3fv( &skinnedNormal.x );
meshBuilder.TexCoord2fv( 0, &vert.m_TexCoord.x );
meshBuilder.UserData( &skinnedTangentS.x );
if (g_viewerSettings.highlightBone >= 0)
{
float v = 0.0;
for( k = 0; k < vert.m_NumBones; k++ )
{
if (vert.m_BoneIndex[k] == g_viewerSettings.highlightBone)
{
v = vert.m_BoneWeight[k];
}
}
v = clamp( v, 0.0f, 1.0f );
meshBuilder.Color4f( 1.0f - v, 1.0f, 1.0f - v, 0.5 );
}
else
{
switch( vert.m_NumBones )
{
case 0:
meshBuilder.Color3f( 0.0f, 0.0f, 0.0f );
break;
case 1:
meshBuilder.Color3f( 0.0f, 1.0f, 0.0f );
break;
case 2:
meshBuilder.Color3f( 1.0f, 1.0f, 0.0f );
break;
case 3:
meshBuilder.Color3f( 1.0f, 0.0f, 0.0f );
break;
default:
meshBuilder.Color3f( 1.0f, 1.0f, 1.0f );
break;
}
}
meshBuilder.AdvanceVertex();
}
int i;
// Set the indices down to the hardware.
// Each triplet of indices is a triangle.
for( i = 0; i < materialBatch.m_TriListIndices.Count(); i++ )
{
meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
}
meshBuilder.End();
pBuildMesh->Draw();
}
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PopMatrix();
return 0;
}
int DebugDrawModelTexCoord( IStudioRender *pStudioRender, const char *pMaterialName, const DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, float w, float h )
{
// Make static so that we aren't reallocating everything all the time.
// TODO: make sure that this actually keeps us from reallocating inside of GetTriangles.
static GetTriangles_Output_t tris;
pStudioRender->GetTriangles( info, pBoneToWorld, tris );
CUtlVector<int> batchList;
for( int batchID = 0; batchID < tris.m_MaterialBatches.Count(); batchID++ )
{
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchID];
if ( !materialBatch.m_Verts.Count() || V_stricmp(materialBatch.m_pMaterial->GetName(), pMaterialName) )
continue;
batchList.AddToTail(batchID);
}
if ( !batchList.Count() )
return 0;
bool bFound = false;
IMaterialVar *pBaseVar = g_materialDebugCopyBaseTexture->FindVar( "$basetexture", &bFound, true );
if ( !bFound )
return 0;
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchList[0]];
IMaterialVar *pVar = materialBatch.m_pMaterial->FindVar( "$basetexture", &bFound, true );
if ( !bFound )
return 0;
pBaseVar->SetTextureValue( pVar->GetTextureValue() );
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->OverrideDepthEnable( false, false );
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
pRenderContext->Ortho( 0, h, w, 0, -1, 1 );
pRenderContext->MatrixMode( MATERIAL_VIEW );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
CMeshBuilder meshBuilder;
// now render a single quad with the base texture on it
{
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchList[0]];
//pRenderContext->Bind( materialBatch.m_pMaterial );
pRenderContext->Bind( g_materialDebugCopyBaseTexture );
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, 4, 6 );
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[0];
//const Vector &pos = vert.m_Position;
const Vector &normal = vert.m_Normal;
const Vector4D &tangentS = vert.m_TangentS;
Vector uv0(0,0,0), uv1(1,0,0), uv2(1, 1, 0), uv3(0,1,0);
Vector *pUV[] = {&uv0, &uv1, &uv2, &uv3};
for ( int i = 0;i < 4; i++ )
{
Vector p = *pUV[i];
p.x *= w;
p.y *= h;
meshBuilder.Position3fv( &p.x );
meshBuilder.Normal3fv( &normal.x );
meshBuilder.TexCoord2fv( 0, pUV[i]->Base() );
meshBuilder.UserData( &tangentS.x );
meshBuilder.Color3f( 1.0f, 1.0f, 1.0f );
meshBuilder.AdvanceVertex();
}
meshBuilder.FastIndex( 0 );
meshBuilder.FastIndex( 1 );
meshBuilder.FastIndex( 2 );
meshBuilder.FastIndex( 0 );
meshBuilder.FastIndex( 2 );
meshBuilder.FastIndex( 3 );
meshBuilder.End();
pBuildMesh->Draw();
}
// now draw coverage - show which UV space is used more than once
#if 0
for( int i = 0; i < batchList.Count(); i++ )
{
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchList[i]];
//pRenderContext->Bind( g_materialWireframeVertexColorNoCull );
pRenderContext->Bind( g_materialVertexColorAdditive );
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(),
materialBatch.m_TriListIndices.Count() );
int vertID;
// Send the vertices down to the hardware.
for( vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
{
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
const Vector &normal = vert.m_Normal;
const Vector4D &tangentS = vert.m_TangentS;
Vector p;
p.x = vert.m_TexCoord.x * w;
p.y = vert.m_TexCoord.y * h;
p.z = 0;
meshBuilder.Position3fv( &p.x );
meshBuilder.Normal3fv( &normal.x );
meshBuilder.UserData( &tangentS.x );
meshBuilder.Color3f( 0.25f, 0.0f, 0.0f );
meshBuilder.AdvanceVertex();
}
int i;
// Set the indices down to the hardware.
// Each triplet of indices is a triangle.
for( i = 0; i < materialBatch.m_TriListIndices.Count(); i++ )
{
meshBuilder.FastIndex( materialBatch.m_TriListIndices[i] );
}
meshBuilder.End();
pBuildMesh->Draw();
}
#endif
const color32 batchColor = {0,255,255,0};
// now draw all batches with the matching material in wireframe over the render of the base texture
for( int i = 0; i < batchList.Count(); i++ )
{
GetTriangles_MaterialBatch_t &materialBatch = tris.m_MaterialBatches[batchList[i]];
pRenderContext->Bind( g_materialWireframeVertexColorNoCull );
IMesh *pBuildMesh = pRenderContext->GetDynamicMesh( false );
meshBuilder.Begin( pBuildMesh, MATERIAL_TRIANGLES, materialBatch.m_Verts.Count(),
materialBatch.m_TriListIndices.Count() );
// Send the vertices down to the hardware.
for( int vertID = 0; vertID < materialBatch.m_Verts.Count(); vertID++ )
{
GetTriangles_Vertex_t &vert = materialBatch.m_Verts[vertID];
const Vector &normal = vert.m_Normal;
const Vector4D &tangentS = vert.m_TangentS;
Vector p;
p.x = vert.m_TexCoord.x * w;
p.y = vert.m_TexCoord.y * h;
p.z = 0;
meshBuilder.Position3fv( &p.x );
meshBuilder.Normal3fv( &normal.x );
meshBuilder.UserData( &tangentS.x );
meshBuilder.Color4ubv( &batchColor.r );
meshBuilder.AdvanceVertex();
}
// Set the indices down to the hardware.
// Each triplet of indices is a triangle.
for( int j = 0; j < materialBatch.m_TriListIndices.Count(); j++ )
{
meshBuilder.FastIndex( materialBatch.m_TriListIndices[j] );
}
meshBuilder.End();
pBuildMesh->Draw();
}
pRenderContext->MatrixMode( MATERIAL_VIEW );
pRenderContext->PopMatrix();
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
pRenderContext->PopMatrix();
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PopMatrix();
return 0;
}

View File

@@ -0,0 +1,30 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef DEBUGDRAWMODEL_H
#define DEBUGDRAWMODEL_H
#ifdef _WIN32
#pragma once
#endif
int DebugDrawModel( IStudioRender *pStudioRender, DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, const Vector &modelOrigin,
int flags = STUDIORENDER_DRAW_ENTIRE_MODEL );
int DebugDrawModelNormals( IStudioRender *pStudioRender, DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, const Vector &modelOrigin,
int flags = STUDIORENDER_DRAW_ENTIRE_MODEL );
int DebugDrawModelTangentS( IStudioRender *pStudioRender, DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, const Vector &modelOrigin,
int flags = STUDIORENDER_DRAW_ENTIRE_MODEL );
int DebugDrawModelTangentT( IStudioRender *pStudioRender, DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, const Vector &modelOrigin,
int flags = STUDIORENDER_DRAW_ENTIRE_MODEL );
int DebugDrawModelBoneWeights( IStudioRender *pStudioRender, DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, const Vector &modelOrigin,
int flags = STUDIORENDER_DRAW_ENTIRE_MODEL );
int DebugDrawModelBadVerts( IStudioRender *pStudioRender, DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, const Vector &modelOrigin,
int flags = STUDIORENDER_DRAW_ENTIRE_MODEL );
int DebugDrawModelWireframe( IStudioRender *pStudioRender, DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, const Vector &modelOrigin,
const Vector &color, int flags = STUDIORENDER_DRAW_ENTIRE_MODEL );
int DebugDrawModelTexCoord( IStudioRender *pStudioRender, const char *pMaterialName, const DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, float w, float h );
#endif // DEBUGDRAWMODEL_H

View File

@@ -0,0 +1,288 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
//
// Half-Life Model Viewer (c) 1999 by Mete Ciragan
//
// file: FileAssociation.cpp
// last modified: May 04 1999, Mete Ciragan
// copyright: The programs and associated files contained in this
// distribution were developed by Mete Ciragan. The programs
// are not in the public domain, but they are freely
// distributable without licensing fees. These programs are
// provided without guarantee or warrantee expressed or
// implied.
//
// version: 1.2
//
// email: mete@swissquake.ch
// web: http://www.swissquake.ch/chumbalum-soft/
//
#include "FileAssociation.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mxtk/mx.h>
FileAssociation *g_FileAssociation = 0;
FileAssociation::FileAssociation ()
: mxWindow (0, 100, 100, 400, 210, "File Associations", mxWindow::Dialog)
{
cExtension = new mxChoice (this, 5, 5, 220, 22, IDC_EXTENSION);
//new mxButton (this, 230, 5, 75, 22, "Add", IDC_ADD);
//new mxButton (this, 310, 5, 75, 22, "Remove", IDC_REMOVE);
new mxGroupBox (this, 5, 30, 380, 115, "Assocations");
rbAction[0] = new mxRadioButton (this, 10, 50, 120, 22, "program", IDC_ACTION1, true);
rbAction[1] = new mxRadioButton (this, 10, 72, 120, 22, "associated program", IDC_ACTION2);
rbAction[2] = new mxRadioButton (this, 10, 94, 120, 22, "HLMV default", IDC_ACTION3);
rbAction[3] = new mxRadioButton (this, 10, 116, 120, 22, "none", IDC_ACTION4);
leProgram = new mxLineEdit (this, 130, 50, 220, 22, "", IDC_PROGRAM);
leProgram->setEnabled (false);
bChooseProgram = new mxButton (this, 352, 50, 22, 22, ">>", IDC_CHOOSEPROGRAM);
bChooseProgram->setEnabled (false);
rbAction[0]->setChecked (false);
rbAction[1]->setChecked (true);
new mxButton (this, 110, 155, 75, 22, "Ok", IDC_OK);
new mxButton (this, 215, 155, 75, 22, "Cancel", IDC_CANCEL);
initAssociations ();
}
FileAssociation::~FileAssociation ()
{
}
int
FileAssociation::handleEvent (mxEvent *event)
{
if (event->event != mxEvent::Action)
return 0;
switch (event->action)
{
case IDC_EXTENSION:
{
int index = cExtension->getSelectedIndex ();
if (index >= 0)
setAssociation (index);
}
break;
case IDC_ACTION1:
case IDC_ACTION2:
case IDC_ACTION3:
case IDC_ACTION4:
{
leProgram->setEnabled (rbAction[0]->isChecked ());
bChooseProgram->setEnabled (rbAction[0]->isChecked ());
int index = cExtension->getSelectedIndex ();
if (index >= 0)
d_associations[index].association = event->action - IDC_ACTION1;
}
break;
case IDC_PROGRAM:
{
int index = cExtension->getSelectedIndex ();
if (index >= 0)
strcpy (d_associations[index].program, leProgram->getLabel ());
}
break;
case IDC_CHOOSEPROGRAM:
{
const char *ptr = mxGetOpenFileName (this, 0, "*.exe");
if (ptr)
{
leProgram->setLabel (ptr);
int index = cExtension->getSelectedIndex ();
if (index >= 0)
strcpy (d_associations[index].program, leProgram->getLabel ());
}
}
break;
case IDC_OK:
saveAssociations ();
case IDC_CANCEL:
setVisible (false);
break;
}
return 1;
}
void
FileAssociation::initAssociations ()
{
int i;
cExtension->removeAll ();
for (i = 0; i < 16; i++)
d_associations[i].association = -1;
char path[256];
strcpy (path, mx::getApplicationPath ());
strcat (path, "/hlmv.fa");
FILE *file = fopen (path, "rt");
if (!file)
return;
i = 0;
char line[256];
while (i < 16 && fgets (line, 256, file))
{
int j = 0;
while (line[++j] != '\"');
line[j] = '\0';
strcpy (d_associations[i].extension, &line[1]);
while (line[++j] != '\"');
int k = j + 1;
while (line[++j] != '\"');
line[j] = '\0';
strcpy (d_associations[i].program, &line[k]);
d_associations[i].association = atoi (&line[++j]);
cExtension->add (d_associations[i].extension);
++i;
}
fclose (file);
setAssociation (0);
}
void
FileAssociation::setAssociation (int index)
{
cExtension->select (index);
leProgram->setLabel (d_associations[index].program);
for (int i = 0; i < 4; i++)
rbAction[i]->setChecked (i == d_associations[index].association);
leProgram->setEnabled (d_associations[index].association == 0);
bChooseProgram->setEnabled (d_associations[index].association == 0);
// TODO: check for valid associtaion
#ifdef WIN32__
char path[256];
strcpy (path, mx_gettemppath ());
strcat (path, "/hlmvtemp.");
strcat (path, d_associations[index].extension);
FILE *file = fopen (path, "wb");
if (file)
fclose (file);
int val = (int) ShellExecute ((HWND) getHandle (), "open", path, 0, 0, SW_HIDE);
char str[32];
sprintf (str, "%d", val);
setLabel (str);
rbAction[1]->setEnabled (val != 31);
/*
WORD dw = 0;
HICON hIcon = ExtractAssociatedIcon ((HINSTANCE) GetWindowLong ((HWND) getHandle (), GWL_HINSTANCE), path, &dw);
SendMessage ((HWND) getHandle (), WM_SETICON, (WPARAM) ICON_SMALL, (LPARAM) hIcon);
char str[32];
sprintf (str, "%d", (int) hIcon);
setLabel (str);
*/
DeleteFile (path);
//DestroyIcon (hIcon);
#endif
rbAction[2]->setEnabled (
!mx_strcasecmp (d_associations[index].extension, "mdl") ||
!mx_strcasecmp (d_associations[index].extension, "tga") ||
!mx_strcasecmp (d_associations[index].extension, "wav")
);
}
void
FileAssociation::saveAssociations ()
{
char path[256];
strcpy (path, mx::getApplicationPath ());
strcat (path, "/hlmv.fa");
FILE *file = fopen (path, "wt");
if (!file)
return;
for (int i = 0; i < 16; i++)
{
if (d_associations[i].association == -1)
break;
fprintf (file, "\"%s\" \"%s\" %d\n",
d_associations[i].extension,
d_associations[i].program,
d_associations[i].association);
}
fclose (file);
}
int
FileAssociation::getMode (char *extension)
{
for (int i = 0; i < 16; i++)
{
//if (!strcmp (d_associations[i].extension, mx_strlower (extension)))
if (!strcmp (d_associations[i].extension, extension))
return d_associations[i].association;
}
return -1;
}
char *
FileAssociation::getProgram (char *extension)
{
for (int i = 0; i < 16; i++)
{
//if (!strcmp (d_associations[i].extension, mx_strlower (extension)))
if (!strcmp (d_associations[i].extension, extension))
return d_associations[i].program;
}
return 0;
}

View File

@@ -0,0 +1,98 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
//
// Half-Life Model Viewer (c) 1999 by Mete Ciragan
//
// file: FileAssociation.h
// last modified: Apr 28 1999, Mete Ciragan
// copyright: The programs and associated files contained in this
// distribution were developed by Mete Ciragan. The programs
// are not in the public domain, but they are freely
// distributable without licensing fees. These programs are
// provided without guarantee or warrantee expressed or
// implied.
//
// version: 1.2
//
// email: mete@swissquake.ch
// web: http://www.swissquake.ch/chumbalum-soft/
//
#ifndef INCLUDED_FILEASSOCIATION
#define INCLUDED_FILEASSOCIATION
#ifndef INCLUDED_MXWINDOW
#include <mxtk/mxWindow.h>
#endif
#define IDC_EXTENSION 1001
#define IDC_ADD 1002
#define IDC_REMOVE 1003
#define IDC_ACTION1 1004
#define IDC_ACTION2 1005
#define IDC_ACTION3 1006
#define IDC_ACTION4 1007
#define IDC_PROGRAM 1008
#define IDC_CHOOSEPROGRAM 1009
#define IDC_OK 1010
#define IDC_CANCEL 1011
typedef struct
{
char extension[16];
char program[256];
int association;
} association_t;
class mxChoice;
class mxRadioButton;
class mxLineEdit;
class mxButton;
class FileAssociation : public mxWindow
{
mxChoice *cExtension;
mxRadioButton *rbAction[4];
mxLineEdit *leProgram;
mxButton *bChooseProgram;
association_t d_associations[16];
void initAssociations ();
void saveAssociations ();
public:
// CREATORS
FileAssociation ();
virtual ~FileAssociation ();
// MANIPULATORS
int handleEvent (mxEvent *event);
void setAssociation (int index);
// ACCESSORS
int getMode (char *extension);
char *getProgram (char *extension);
};
extern FileAssociation *g_FileAssociation;
#endif // INCLUDED_FILEASSOCIATION

84
utils/hlmv/hlmv.rc Normal file
View File

@@ -0,0 +1,84 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
MX_ICON ICON DISCARDABLE "icon1.ico"
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// German (Switzerland) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DES)
#ifdef _WIN32
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_SWISS
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // German (Switzerland) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

204
utils/hlmv/hlmv.vpc Normal file
View File

@@ -0,0 +1,204 @@
//-----------------------------------------------------------------------------
// HLMV.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro SRCDIR "..\.."
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
$Include "$SRCDIR\vpc_scripts\source_exe_base.vpc"
$Configuration
{
$Compiler
{
$AdditionalIncludeDirectories "$BASE,..\common"
$PreprocessorDefinitions "$BASE;VECTOR;PROTECTED_THINGS_DISABLE"
}
$Linker
{
$AdditionalDependencies "$BASE comctl32.lib winmm.lib"
$Version "1.1"
$EntryPoint "mainCRTStartup"
}
}
$Project "Hlmv"
{
$Folder "Source Files"
{
$File "attachments_window.cpp"
$File "controlpanel.cpp"
$File "debugdrawmodel.cpp"
$File "fileassociation.cpp"
$File "matsyswin.cpp"
$File "mdlviewer.cpp"
$File "mxLineEdit2.cpp"
$File "pakviewer.cpp"
$File "physmesh.cpp"
$File "studio_flex.cpp"
$File "studio_render.cpp"
$File "studio_utils.cpp"
$File "sys_win.cpp"
$File "viewersettings.cpp"
}
$Folder "Header Files"
{
$File "anorms.h"
$File "attachments_window.h"
$File "controlpanel.h"
$File "debugdrawmodel.h"
$File "fileassociation.h"
$File "matsyswin.h"
$File "mdlviewer.h"
$File "mxLineEdit2.h"
$File "pakviewer.h"
$File "physmesh.h"
$File "resource.h"
$File "studio_render.h"
$File "studiomodel.h"
$File "sys.h"
$File "viewersettings.h"
}
$Folder "External Source Files"
{
$File "$SRCDIR\public\bone_setup.cpp"
$File "$SRCDIR\public\collisionutils.cpp"
$File "$SRCDIR\public\filesystem_helpers.cpp"
$File "$SRCDIR\public\filesystem_init.cpp"
$File "$SRCDIR\public\jigglebones.cpp"
$File "$SRCDIR\public\studio.cpp"
}
$Folder "External Header Files"
{
$File "$SRCDIR\public\mathlib\amd3dx.h"
$File "$SRCDIR\public\basehandle.h"
$File "$SRCDIR\public\tier0\basetypes.h"
$File "$SRCDIR\public\bitvec.h"
$File "$SRCDIR\public\bone_accessor.h"
$File "$SRCDIR\public\bone_setup.h"
$File "$SRCDIR\public\bspflags.h"
$File "$SRCDIR\public\tier1\characterset.h"
$File "..\common\cmdlib.h"
$File "$SRCDIR\public\cmodel.h"
$File "$SRCDIR\public\CollisionUtils.h"
$File "$SRCDIR\public\tier0\commonmacros.h"
$File "$SRCDIR\public\mathlib\compressed_vector.h"
$File "$SRCDIR\public\const.h"
$File "$SRCDIR\public\vphysics\constraints.h"
$File "$SRCDIR\public\tier0\dbg.h"
$File "debugdrawmodel.h"
$File "$SRCDIR\public\tier0\fasttimer.h"
$File "$SRCDIR\public\filesystem.h"
$File "$SRCDIR\public\filesystem_helpers.h"
$File "$SRCDIR\public\tier1\fmtstr.h"
$File "$SRCDIR\public\gametrace.h"
$File "$SRCDIR\public\appframework\IAppSystem.h"
$File "$SRCDIR\public\tier0\icommandline.h"
$File "$SRCDIR\public\ihandleentity.h"
$File "$SRCDIR\public\materialsystem\imaterial.h"
$File "$SRCDIR\public\materialsystem\imaterialproxyfactory.h"
$File "$SRCDIR\public\materialsystem\imaterialsystem.h"
$File "$SRCDIR\public\materialsystem\imaterialsystemhardwareconfig.h"
$File "$SRCDIR\public\materialsystem\imaterialvar.h"
$File "$SRCDIR\public\materialsystem\imesh.h"
$File "$SRCDIR\public\tier1\interface.h"
$File "$SRCDIR\public\ISpatialPartition.h"
$File "$SRCDIR\public\istudiorender.h"
$File "$SRCDIR\public\materialsystem\itexture.h"
$File "$SRCDIR\public\jigglebones.h"
$File "$SRCDIR\public\materialsystem\materialsystem_config.h"
$File "$SRCDIR\public\mathlib\mathlib.h"
$File "$SRCDIR\public\tier0\memdbgoff.h"
$File "$SRCDIR\public\tier0\memdbgon.h"
$File "$SRCDIR\public\tier1\mempool.h"
$File "$SRCDIR\public\mouthinfo.h"
$File "$SRCDIR\public\phyfile.h"
$File "..\common\physdll.h"
$File "$SRCDIR\public\tier0\platform.h"
$File "$SRCDIR\public\tier0\protected_things.h"
$File "$SRCDIR\public\vstdlib\random.h"
$File "$SRCDIR\public\string_t.h"
$File "$SRCDIR\public\tier1\strtools.h"
$File "$SRCDIR\public\studio.h"
$File "$SRCDIR\public\texture_group_names.h"
$File "$SRCDIR\public\tier1\utlbuffer.h"
$File "$SRCDIR\public\tier1\utldict.h"
$File "$SRCDIR\public\tier1\utllinkedlist.h"
$File "$SRCDIR\public\tier1\utlmemory.h"
$File "$SRCDIR\public\tier1\utlrbtree.h"
$File "$SRCDIR\public\tier1\utlsymbol.h"
$File "$SRCDIR\public\tier1\utlvector.h"
$File "$SRCDIR\public\vcollide.h"
$File "$SRCDIR\public\vcollide_parse.h"
$File "$SRCDIR\public\mathlib\vector.h"
$File "$SRCDIR\public\mathlib\vector2d.h"
$File "$SRCDIR\public\mathlib\vector4d.h"
$File "$SRCDIR\public\mathlib\vmatrix.h"
$File "$SRCDIR\public\vphysics_interface.h"
$File "$SRCDIR\public\mathlib\vplane.h"
$File "$SRCDIR\public\tier0\vprof.h"
$File "$SRCDIR\public\vstdlib\vstdlib.h"
$Folder "mxtk"
{
$File "..\..\public\mxtk\mx.h"
$File "..\..\public\mxtk\mxBmp.h"
$File "..\..\public\mxtk\mxButton.h"
$File "..\..\public\mxtk\mxCheckBox.h"
$File "..\..\public\mxtk\mxChoice.h"
$File "..\..\public\mxtk\mxChooseColor.h"
$File "..\..\public\mxtk\mxEvent.h"
$File "..\..\public\mxtk\mxFileDialog.h"
$File "..\..\public\mxtk\mxGlWindow.h"
$File "..\..\public\mxtk\mxGroupBox.h"
$File "..\..\public\mxtk\mxImage.h"
$File "..\..\public\mxtk\mxInit.h"
$File "..\..\public\mxtk\mxLabel.h"
$File "..\..\public\mxtk\mxLineEdit.h"
$File "mxLineEdit2.h"
$File "..\..\public\mxtk\mxLinkedList.h"
$File "..\..\public\mxtk\mxListBox.h"
$File "..\..\public\mxtk\mxMatSysWindow.h"
$File "..\..\public\mxtk\mxMenu.h"
$File "..\..\public\mxtk\mxMenuBar.h"
$File "..\..\public\mxtk\mxMessageBox.h"
$File "..\..\public\mxtk\mxpath.h"
$File "..\..\public\mxtk\mxPcx.h"
$File "..\..\public\mxtk\mxPopupMenu.h"
$File "..\..\public\mxtk\mxProgressBar.h"
$File "..\..\public\mxtk\mxRadioButton.h"
$File "..\..\public\mxtk\mxScrollbar.h"
$File "..\..\public\mxtk\mxSlider.h"
$File "..\..\public\mxtk\mxstring.h"
$File "..\..\public\mxtk\mxTab.h"
$File "..\..\public\mxtk\mxTga.h"
$File "..\..\public\mxtk\mxToggleButton.h"
$File "..\..\public\mxtk\mxToolTip.h"
$File "..\..\public\mxtk\mxTreeView.h"
$File "..\..\public\mxtk\mxWidget.h"
$File "..\..\public\mxtk\mxWindow.h"
}
}
$Folder "Resources"
{
$File "hlmv.rc"
$File "icon1.ico"
$File "resource.h"
}
$Folder "Link Libraries"
{
$Lib tier2
$Lib appframework
$Lib bitmap
$Lib mathlib
$Lib $LIBCOMMON\mxtoolkitwin32
}
}

BIN
utils/hlmv/icon1.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

59
utils/hlmv/makefile Normal file
View File

@@ -0,0 +1,59 @@
# simple Makefile for Half-Life Model Viewer
CC = g++
CFLAGS = -O2
IFLAGS =
LFLAGS = -s
LIBS = -lmxtk-qt -lqt -lqgl -lGL -lGLU -lXaw
HLMV = ../bin/hlmv
OBJS = \
ControlPanel.o \
FileAssociation.o \
GlWindow.o \
ViewerSettings.o \
mathlib.o \
mdlviewer.o \
pakviewer.o \
studio_render.o \
studio_utils.o \
all: $(HLMV)
$(HLMV): $(OBJS)
$(CC) $(LFLAGS) -o $(HLMV) $(OBJS) $(LIBS)
ControlPanel.o: ControlPanel.cpp ControlPanel.h ViewerSettings.h StudioModel.h GlWindow.h
$(CC) -c $(CFLAGS) $(IFLAGS) ControlPanel.cpp
FileAssociation.o: FileAssociation.cpp FileAssociation.h
$(CC) -c $(CFLAGS) $(IFLAGS) FileAssociation.cpp
GlWindow.o: GlWindow.cpp GlWindow.h StudioModel.h ViewerSettings.h
$(CC) -c $(CFLAGS) $(IFLAGS) GlWindow.cpp
ViewerSettings.o: ViewerSettings.cpp ViewerSettings.h
$(CC) -c $(CFLAGS) $(IFLAGS) ViewerSettings.cpp
mathlib.o: mathlib.c mathlib.h
$(CC) -c $(CFLAGS) $(IFLAGS) mathlib.c
mdlviewer.o: mdlviewer.cpp mdlviewer.h GlWindow.h ControlPanel.h StudioModel.h pakviewer.h FileAssociation.h
$(CC) -c $(CFLAGS) $(IFLAGS) mdlviewer.cpp
pakviewer.o: pakviewer.cpp pakviewer.h mdlviewer.h GlWindow.h ControlPanel.h StudioModel.h FileAssociation.h
$(CC) -c $(CFLAGS) $(IFLAGS) pakviewer.cpp
studio_render.o: studio_render.cpp StudioModel.h ViewerSettings.h
$(CC) -c $(CFLAGS) $(IFLAGS) studio_render.cpp
studio_utils.o: studio_utils.cpp StudioModel.h
$(CC) -c $(CFLAGS) $(IFLAGS) studio_utils.cpp
# clean
clean:
rm *.o

1182
utils/hlmv/matsyswin.cpp Normal file

File diff suppressed because it is too large Load Diff

179
utils/hlmv/matsyswin.h Normal file
View File

@@ -0,0 +1,179 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#ifndef MATSYSWIN_H
#define MATSYSWIN_H
#ifdef _WIN32
#pragma once
#endif
#include <mxtk/mxMatSysWindow.h>
#include "materialsystem/imaterialsystem.h"
#include "interface.h"
class ITexture;
class MatSysWindow : public mxMatSysWindow
{
public:
// CREATORS
MatSysWindow( mxWindow *parent, int x, int y, int w, int h, const char *label, int style );
~MatSysWindow( );
// MANIPULATORS
void dumpViewport (const char *filename);
virtual int handleEvent( mxEvent *event );
virtual void draw( );
void *m_hWnd;
// void *m_hDC;
CSysModule *m_hMaterialSystemInst;
ITexture *m_pCubemapTexture;
};
extern MatSysWindow *g_MatSysWindow;
extern IMaterial *g_materialBackground;
extern IMaterial *g_materialWireframe;
extern IMaterial *g_materialWireframeVertexColor;
extern IMaterial *g_materialWireframeVertexColorNoCull;
extern IMaterial *g_materialDebugCopyBaseTexture;
extern IMaterial *g_materialFlatshaded;
extern IMaterial *g_materialSmoothshaded;
extern IMaterial *g_materialBones;
extern IMaterial *g_materialLines;
extern IMaterial *g_materialFloor;
extern IMaterial *g_materialVertexColor;
extern IMaterial *g_materialShadow;
#if 0
typedef struct
{
int width;
int height;
int bpp;
int flags;
int frequency;
} screen_res_t;
typedef struct
{
int width;
int height;
int bpp;
} devinfo_t;
class MaterialSystemApp
{
public:
MaterialSystemApp();
~MaterialSystemApp();
void Term();
// Post a message to shutdown the app.
void AppShutdown();
int WinMain(void *hInstance, void *hPrevInstance, char *szCmdLine, int iCmdShow);
long WndProc(void *hwnd, long iMsg, long wParam, long lParam);
int FindNumParameter(const char *s, int defaultVal=-1);
bool FindParameter(const char *s);
const char* FindParameterArg(const char *s);
void SetTitleText(PRINTF_FORMAT_STRING const char *fmt, ...);
private:
bool InitMaterialSystem();
void Clear();
bool CreateMainWindow(int width, int height, int bpp, bool fullscreen);
void RenderScene();
void MouseCapture();
void MouseRelease();
void GetParameters();
public:
IMaterialSystem *m_pMaterialSystem;
void *m_hMaterialSystemInst;
devinfo_t m_DevInfo;
void *m_hInstance;
int m_iCmdShow;
void *m_hWnd;
void *m_hDC;
bool m_bActive;
bool m_bFullScreen;
int m_width;
int m_height;
int m_centerx; // for mouse offset calculations
int m_centery;
int m_bpp;
BOOL m_bChangeBPP;
BOOL m_bAllowSoft;
BOOL m_bPaused;
int m_glnWidth;
int m_glnHeight;
float m_gldAspect;
float m_NearClip;
float m_FarClip;
float m_fov;
screen_res_t *m_pResolutions;
int m_iResCount;
int m_iVidMode;
};
// ---------------------------------------------------------------------------------------- //
// Global functions
// ---------------------------------------------------------------------------------------- //
// Show an error dialog and quit.
bool Sys_Error(PRINTF_FORMAT_STRING const char *pMsg, ...);
// Print to the trace window.
void con_Printf(PRINTF_FORMAT_STRING const char *pMsg, ...);
// Returns true if the key is down.
bool IsKeyDown(char key);
extern MaterialSystemApp g_MaterialSystemApp;
extern unsigned int g_Time;
#endif
#endif // GLAPP_H

1631
utils/hlmv/mdlviewer.cpp Normal file

File diff suppressed because it is too large Load Diff

163
utils/hlmv/mdlviewer.h Normal file
View File

@@ -0,0 +1,163 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
//
// Half-Life Model Viewer (c) 1999 by Mete Ciragan
//
// file: mdlviewer.h
// last modified: Apr 28 1999, Mete Ciragan
// copyright: The programs and associated files contained in this
// distribution were developed by Mete Ciragan. The programs
// are not in the public domain, but they are freely
// distributable without licensing fees. These programs are
// provided without guarantee or warrantee expressed or
// implied.
//
// version: 1.2
//
// email: mete@swissquake.ch
// web: http://www.swissquake.ch/chumbalum-soft/
//
#ifndef INCLUDED_MDLVIEWER
#define INCLUDED_MDLVIEWER
#ifndef INCLUDED_MXWINDOW
#include "mxWindow.h"
#endif
#define IDC_FILE_LOADMODEL 1001
#define IDC_FILE_LOADBACKGROUNDTEX 1002
#define IDC_FILE_LOADGROUNDTEX 1003
#define IDC_FILE_UNLOADGROUNDTEX 1004
#define IDC_FILE_CLOSEPAKFILE 1007
#define IDC_FILE_RECENTMODELS1 1008
#define IDC_FILE_RECENTMODELS2 1009
#define IDC_FILE_RECENTMODELS3 1010
#define IDC_FILE_RECENTMODELS4 1011
#define IDC_FILE_RECENTMODELS5 1012
#define IDC_FILE_RECENTMODELS6 1013
#define IDC_FILE_RECENTMODELS7 1014
#define IDC_FILE_RECENTMODELS8 1015
#define IDC_FILE_EXIT 1016
#define IDC_FILE_REFRESH 1017
#define IDC_FILE_LOADMERGEDMODEL 1018
#define IDC_FILE_UNLOADMERGEDMODEL 1019
#define IDC_FILE_LOADMODEL_STEAM 1020
#define IDC_FILE_LOADMERGEDMODEL_STEAM 1021
#define IDC_FLUSH_SHADERS 1022
#define IDC_OPTIONS_COLORBACKGROUND 1101
#define IDC_OPTIONS_COLORGROUND 1102
#define IDC_OPTIONS_COLORLIGHT 1103
#define IDC_OPTIONS_COLORAMBIENT 1104
#define IDC_OPTIONS_CENTERVIEW 1105
#define IDC_OPTIONS_CENTERVERTS 1106
#define IDC_OPTIONS_MAKESCREENSHOT 1107
#define IDC_OPTIONS_DUMP 1108
#define IDC_OPTIONS_VIEWMODEL 1109
#define IDC_OPTIONS_SYNCHLMVCAMERA 1110
#define IDC_OPTIONS_LINKHLMV 1111
#define IDC_OPTIONS_UNLINKHLMV 1112
#define IDC_VIEW_FILEASSOCIATIONS 1201
#define IDC_VIEW_ACTIVITIES 1202
#define IDC_VIEW_HIDDEN 1203
#define IDC_HELP_GOTOHOMEPAGE 1301
#define IDC_HELP_ABOUT 1302
// Keyboard accelerators (not items on any menu...checkboxes on Render tab)
#define IDC_ACCEL_WIREFRAME 1401
#define IDC_ACCEL_ATTACHMENTS 1402
#define IDC_ACCEL_GROUND 1403
#define IDC_ACCEL_HITBOXES 1404
#define IDC_ACCEL_BONES 1405
#define IDC_ACCEL_BACKGROUND 1406
#define IDC_ACCEL_MOVEMENT 1407
#define IDC_ACCEL_NORMALS 1408
#define IDC_ACCEL_TANGENTS 1409
#define IDC_ACCEL_SHADOW 1410
#define IDC_FILE_UNLOADMERGEDMODEL1 1414
#define IDC_FILE_UNLOADMERGEDMODEL2 1415
#define IDC_FILE_UNLOADMERGEDMODEL3 1416
#define IDC_FILE_UNLOADMERGEDMODEL4 1417
#define IDC_FILE_UNLOADMERGEDMODEL5 1418
#define IDC_FILE_UNLOADMERGEDMODEL6 1419
#define IDC_FILE_UNLOADMERGEDMODEL7 1420
#define IDC_FILE_UNLOADMERGEDMODEL8 1421
#define IDC_FILE_UNLOADMERGEDMODEL9 1422
#define IDC_FILE_UNLOADMERGEDMODEL10 1423
#define IDC_FILE_UNLOADMERGEDMODEL11 1424
#define IDC_FILE_UNLOADMERGEDMODEL12 1425
#define IDC_FILE_UNLOADALLMERGEDMODELS 1430
class mxMenuBar;
class MatSysWindow;
class ControlPanel;
class mxMenu;
enum { Action, Size, Timer, Idle, Show, Hide,
MouseUp, MouseDown, MouseMove, MouseDrag,
KeyUp, KeyDown
};
class MDLViewer : public mxWindow
{
mxMenuBar *mb;
MatSysWindow *d_MatSysWindow;
ControlPanel *d_cpl;
mxMenu *menuOptions;
mxMenu *menuView;
void loadRecentFiles ();
void saveRecentFiles ();
void initRecentFiles ();
public:
// CREATORS
MDLViewer ();
~MDLViewer ();
// MANIPULATORS
virtual int handleEvent (mxEvent *event);
void SendModelTransformToLinkedHlmv();
void SendLightRotToLinkedHlmv();
void redraw ();
void handleIpcCommand( char *szCommand );
void Refresh( void );
void LoadModelFile( const char *pszFile, int slot = -1 );
void SaveScreenShot( const char *pszFile );
void DumpText( const char *pszFile );
// ACCESSORS
mxMenuBar *getMenuBar () const { return mb; }
MatSysWindow *getMatSysWindow () const { return d_MatSysWindow; }
int GetCurrentHitboxSet( void );
private:
const char* SteamGetOpenFilename();
};
extern MDLViewer *g_MDLViewer;
extern char g_appTitle[];
#endif // INCLUDED_MDLVIEWER

View File

@@ -0,0 +1,31 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include <windows.h>
#include <richedit.h>
#include "mxLineEdit2.h"
mxLineEdit2::mxLineEdit2( mxWindow *parent, int x, int y, int w, int h, const char *label, int id, int style )
: mxLineEdit( parent, x, y, w, h, label, id, style )
{
}
void mxLineEdit2::getText( char *pOut, int len )
{
GetWindowText( (HWND) getHandle (), pOut, len );
pOut[len-1] = 0;
}
void mxLineEdit2::setText( const char *pText )
{
setLabel( "%s", pText );
}

31
utils/hlmv/mxLineEdit2.h Normal file
View File

@@ -0,0 +1,31 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef MXLINEEDIT2_H
#define MXLINEEDIT2_H
#ifdef _WIN32
#pragma once
#endif
#ifndef INCLUDED_MXWINDOW
#include <mxtk/mxWindow.h>
#endif
#include <mxtk/mxLineEdit.h>
// Extends the (mostly unimplemented) mxLineEdit control.
class mxLineEdit2 : public mxLineEdit
{
public:
mxLineEdit2( mxWindow *parent, int x, int y, int w, int h, const char *label = 0, int id = 0, int style = 0 );
void getText( char *pOut, int len );
void setText( const char *pText );
};
#endif // MXLINEEDIT2_H

516
utils/hlmv/pakviewer.cpp Normal file
View File

@@ -0,0 +1,516 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
//
// Half-Life Model Viewer (c) 1999 by Mete Ciragan
//
// file: pakviewer.cpp
// last modified: May 04 1999, Mete Ciragan
// copyright: The programs and associated files contained in this
// distribution were developed by Mete Ciragan. The programs
// are not in the public domain, but they are freely
// distributable without licensing fees. These programs are
// provided without guarantee or warrantee expressed or
// implied.
//
// version: 1.2
//
// email: mete@swissquake.ch
// web: http://www.swissquake.ch/chumbalum-soft/
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mxtk/mx.h>
#include "pakviewer.h"
#include "mdlviewer.h"
// #include "GlWindow.h"
#include "StudioModel.h"
#include "ControlPanel.h"
#include "FileAssociation.h"
int
pak_ExtractFile (const char *pakFile, const char *lumpName, char *outFile)
{
FILE *file = fopen (pakFile, "rb");
if (!file)
return 0;
int ident, dirofs, dirlen;
fread (&ident, sizeof (int), 1, file);
if (ident != (int) (('K' << 24) + ('C' << 16) + ('A' << 8) + 'P'))
{
fclose (file);
return 0;
}
fread (&dirofs, sizeof (int), 1, file);
fread (&dirlen, sizeof (int), 1, file);
fseek (file, dirofs, SEEK_SET);
int numLumps = dirlen / 64;
for (int i = 0; i < numLumps; i++)
{
char name[56];
int filepos, filelen;
fread (name, 56, 1, file);
fread (&filepos, sizeof (int), 1, file);
fread (&filelen, sizeof (int), 1, file);
if (!mx_strcasecmp (name, lumpName))
{
FILE *out = fopen (outFile, "wb");
if (!out)
{
fclose (file);
return 0;
}
fseek (file, filepos, SEEK_SET);
while (filelen--)
fputc (fgetc (file), out);
fclose (out);
fclose (file);
return 1;
}
}
fclose (file);
return 0;
}
PAKViewer::PAKViewer (mxWindow *window)
: mxWindow (window, 0, 0, 0, 0, "", mxWindow::Normal)
{
strcpy (d_pakFile, "");
strcpy (d_currLumpName, "");
tvPAK = new mxTreeView (this, 0, 0, 0, 0, IDC_PAKVIEWER);
pmMenu = new mxPopupMenu ();
pmMenu->add ("Load Model", 1);
pmMenu->addSeparator ();
pmMenu->add ("Load Background", 2);
pmMenu->add ("Load Ground", 3);
pmMenu->addSeparator ();
pmMenu->add ("Play Sound", 4);
pmMenu->addSeparator ();
pmMenu->add ("Extract File...", 5);
setLoadEntirePAK (true);
setVisible (false);
}
PAKViewer::~PAKViewer ()
{
//tvPAK->remove (0);
//tvPAK->remove();
closePAKFile ();
}
void
_makeTempFileName (char *str, const char *suffix)
{
strcpy (str, mx_gettemppath ());
strcat (str, "/hltempmodel");
strcat (str, suffix);
}
int
PAKViewer::handleEvent (mxEvent *event)
{
switch (event->event)
{
case mxEvent::Action:
{
switch (event->action)
{
case IDC_PAKVIEWER: // tvPAK
if (event->flags & mxEvent::RightClicked)
{
pmMenu->setEnabled (1, strstr (d_currLumpName, ".mdl") != 0);
pmMenu->setEnabled (2, strstr (d_currLumpName, ".tga") != 0);
pmMenu->setEnabled (3, strstr (d_currLumpName, ".tga") != 0);
pmMenu->setEnabled (4, strstr (d_currLumpName, ".wav") != 0);
int ret = pmMenu->popup (tvPAK, event->x, event->y);
switch (ret)
{
case 1:
OnLoadModel ();
break;
case 2:
OnLoadTexture (0);
break;
case 3:
OnLoadTexture (1);
break;
case 4:
OnPlaySound ();
break;
case 5:
OnExtract ();
break;
}
}
else if (event->flags & mxEvent::DoubleClicked)
{
OnPAKViewer ();
char e[16];
strncpy (e, mx_getextension (d_currLumpName), 16);
int mode = g_FileAssociation->getMode (&e[1]);
if (mode == -1)
return 1;
char *program = g_FileAssociation->getProgram (&e[1]);
#ifdef WIN32
if (mode == 0)
{
char str[256];
_makeTempFileName (str, e);
if (!pak_ExtractFile (d_pakFile, d_currLumpName, str))
mxMessageBox (this, "Error extracting from PAK file.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
else
{
if (program)
{
char path[256];
strcpy (path, program);
strcat (path, " ");
strcat (path, str);
if ((int) WinExec (path, SW_SHOW) <= 32)
mxMessageBox (this, "Error executing specified program.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
}
}
}
// associated program
else if (mode == 1)
{
char str[256];
_makeTempFileName (str, e);
if (!pak_ExtractFile (d_pakFile, d_currLumpName, str))
mxMessageBox (this, "Error extracting from PAK file.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
else
if ((int) ShellExecute ((HWND) getHandle (), "open", str, 0, 0, SW_SHOW) <= 32)
mxMessageBox (this, "Error executing document with associated program.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
}
// HLMV default
else
#endif
if (mode == 2)
{
if (!strcmp (e, ".mdl"))
OnLoadModel ();
else if (!strcmp (e, ".tga"))
OnLoadTexture (0);
else if (!strcmp (e, ".wav"))
OnPlaySound ();
return 1;
}
}
return OnPAKViewer ();
} // event->action
} // mxEvent::Action
break;
case mxEvent::Size:
{
tvPAK->setBounds (0, 0, event->width, event->height);
} // mxEvent::Size
break;
} // event->event
return 1;
}
int
PAKViewer::OnPAKViewer ()
{
mxTreeViewItem *tvi = tvPAK->getSelectedItem ();
if (tvi)
{
strcpy (d_currLumpName, tvPAK->getLabel (tvi));
// find the full lump name
mxTreeViewItem *tviParent = tvPAK->getParent (tvi);
char tmp[128];
while (tviParent)
{
strcpy (tmp, d_currLumpName);
strcpy (d_currLumpName, tvPAK->getLabel (tviParent));
strcat (d_currLumpName, "/");
strcat (d_currLumpName, tmp);
tviParent = tvPAK->getParent (tviParent);
}
if (!d_loadEntirePAK)
{
// finally insert "models/"
strcpy (tmp, d_currLumpName);
strcpy (d_currLumpName, "models/");
strcat (d_currLumpName, tmp);
}
}
return 1;
}
int PAKViewer::OnLoadModel ()
{
static char str2[256];
char suffix[16];
strcpy (suffix, ".mdl");
_makeTempFileName (str2, suffix);
if (!pak_ExtractFile (d_pakFile, d_currLumpName, str2))
{
mxMessageBox (this, "Error extracting from PAK file.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
return 1;
}
g_pStudioModel->FreeModel ( false );
if( !g_pStudioModel->LoadModel (str2) )
{
mxMessageBox (this, "Error reading model header.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
return 1;
}
return 1;
}
int PAKViewer::OnLoadTexture (int pos)
{
static char str2[256];
char suffix[16] = "";
if (strstr (d_currLumpName, ".tga"))
sprintf (suffix, "%d%s", pos, ".tga");
_makeTempFileName (str2, suffix);
if (!pak_ExtractFile (d_pakFile, d_currLumpName, str2))
{
mxMessageBox (this, "Error extracting from PAK file.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
return 1;
}
if (0 /* g_MDLViewer->getGlWindow ()->loadTexture (str2, pos) */)
{
if (pos == 0)
g_ControlPanel->setShowBackground (true);
else
g_ControlPanel->setShowGround (true);
}
else
mxMessageBox (this, "Error loading texture.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
return 1;
}
int
PAKViewer::OnPlaySound ()
{
#ifdef WIN32
static char str2[256];
char suffix[16] = "";
// stop any playing sound
PlaySound (0, 0, SND_FILENAME | SND_ASYNC);
if (strstr (d_currLumpName, ".wav"))
sprintf (suffix, "%d%s", 44, ".wav");
_makeTempFileName (str2, suffix);
if (!pak_ExtractFile (d_pakFile, d_currLumpName, str2))
{
mxMessageBox (this, "Error extracting from PAK file.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
return 1;
}
PlaySound (str2, 0, SND_FILENAME | SND_ASYNC);
#endif
return 1;
}
int
PAKViewer::OnExtract ()
{
char *ptr = (char *) mxGetSaveFileName (this, "", "*.*");
if (ptr)
{
if (!pak_ExtractFile (d_pakFile, d_currLumpName, ptr))
mxMessageBox (this, "Error extracting from PAK file.", g_appTitle, MX_MB_OK | MX_MB_ERROR);
}
return 1;
}
int
_compare(const void *arg1, const void *arg2)
{
if (strchr ((char *) arg1, '/') && !strchr ((char *) arg2, '/'))
return -1;
else if (!strchr ((char *) arg1, '/') && strchr ((char *) arg2, '/'))
return 1;
else
return strcmp ((char *) arg1, (char *) arg2);
}
bool
PAKViewer::openPAKFile (const char *pakFile)
{
FILE *file = fopen (pakFile, "rb");
if (!file)
return false;
int ident, dirofs, dirlen;
// check for id
fread (&ident, sizeof (int), 1, file);
if (ident != (int) (('K' << 24) + ('C' << 16) + ('A' << 8) + 'P'))
{
fclose (file);
return false;
}
// load lumps
fread (&dirofs, sizeof (int), 1, file);
fread (&dirlen, sizeof (int), 1, file);
int numLumps = dirlen / 64;
fseek (file, dirofs, SEEK_SET);
lump_t *lumps = new lump_t[numLumps];
if (!lumps)
{
fclose (file);
return false;
}
fread (lumps, sizeof (lump_t), numLumps, file);
fclose (file);
qsort (lumps, numLumps, sizeof (lump_t), _compare);
// save pakFile for later
strcpy (d_pakFile, pakFile);
tvPAK->remove (0);
char namestack[32][32];
mxTreeViewItem *tvistack[32];
for (int k = 0; k < 32; k++)
{
strcpy (namestack[k], "");
tvistack[k] = 0;
}
for (int i = 0; i < numLumps; i++)
{
if (d_loadEntirePAK || !strncmp (lumps[i].name, "models", 6))
{
char *tok;
if (d_loadEntirePAK)
tok = &lumps[i].name[0];
else
tok = &lumps[i].name[7];
int i = 1;
while (tok)
{
char *end = strchr (tok, '/');
if (end)
*end = '\0';
if (strcmp (namestack[i], tok))
{
strcpy (namestack[i], tok);
/*
if (i == 0)
tvistack[i] = tvPAK->add (0, tok);
else*/
tvistack[i] = tvPAK->add (tvistack[i - 1], tok);
for (int j = i + 1; j < 32; j++)
{
strcpy (namestack[j], "");
tvistack[j] = 0;
}
}
++i;
if (end)
tok = end + 1;
else
tok = 0;
}
}
}
delete[] lumps;
setVisible (true);
return true;
}
void
PAKViewer::closePAKFile ()
{
strcpy (d_pakFile, "");
setVisible (false);
}

99
utils/hlmv/pakviewer.h Normal file
View File

@@ -0,0 +1,99 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
//
// Half-Life Model Viewer (c) 1999 by Mete Ciragan
//
// file: pakviewer.h
// last modified: Apr 28 1999, Mete Ciragan
// copyright: The programs and associated files contained in this
// distribution were developed by Mete Ciragan. The programs
// are not in the public domain, but they are freely
// distributable without licensing fees. These programs are
// provided without guarantee or warrantee expressed or
// implied.
//
// version: 1.2
//
// email: mete@swissquake.ch
// web: http://www.swissquake.ch/chumbalum-soft/
//
#ifndef INCLUDED_PAKVIEWER
#define INCLUDED_PAKVIEWER
#ifndef INCLUDED_MXWINDOW
#include "mxWindow.h"
#endif
#define IDC_PAKVIEWER 1001
typedef struct
{
char name[56];
int filepos;
int filelen;
} lump_t;
#ifdef __cpluspus
extern "C" {
#endif
int pak_ExtractFile (const char *pakFile, const char *lumpName, char *outFile);
#ifdef __cpluspus
}
#endif
class mxTreeView;
class mxButton;
class mxPopupMenu;
// class GlWindow;
class PAKViewer : public mxWindow
{
char d_pakFile[256];
char d_currLumpName[256];
bool d_loadEntirePAK;
mxTreeView *tvPAK;
mxPopupMenu *pmMenu;
public:
// CREATORS
PAKViewer (mxWindow *window);
~PAKViewer ();
// MANIPULATORS
virtual int handleEvent (mxEvent *event);
int OnPAKViewer ();
int OnLoadModel ();
int OnLoadTexture (int pos);
int OnPlaySound ();
int OnExtract ();
bool openPAKFile (const char *pakFile);
void closePAKFile ();
void setLoadEntirePAK (bool b) { d_loadEntirePAK = b; }
// ACCESSORS
bool getLoadEntirePAK () const { return d_loadEntirePAK; }
};
#endif // INCLUDED_PAKVIEWER

619
utils/hlmv/physmesh.cpp Normal file
View File

@@ -0,0 +1,619 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
/***
*
* Copyright (c) 1998, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "filesystem.h"
#include "vphysics/constraints.h"
#include "phyfile.h"
#include "physdll.h"
#include "physmesh.h"
#include "mathlib/mathlib.h"
#include <stddef.h>
#include "utlvector.h"
#include "commonmacros.h"
#include "studiomodel.h"
#include "tier1/strtools.h"
#include "bone_setup.h"
#include "fmtstr.h"
#include "vcollide_parse.h"
int FindPhysprop( const char *pPropname );
bool LoadPhysicsProperties( void );
extern int FindBoneIndex( CStudioHdr *pstudiohdr, const char *pName );
struct collisionpair_t
{
int object0;
int object1;
collisionpair_t *pNext;
};
class CStudioPhysics : public IStudioPhysics
{
public:
CStudioPhysics( void )
{
m_pList = NULL;
m_listCount = 0;
m_mass = 0;
m_noselfCollisions = false;
m_pCollisionPairs = NULL;
memset( &m_edit, 0, sizeof(editparams_t) );
}
~CStudioPhysics( void )
{
if ( physcollision )
{
for ( int i = 0; i < m_listCount; i++ )
{
physcollision->DestroyDebugMesh( m_pList[i].m_vertCount, m_pList[i].m_pVerts );
physcollision->DestroyQueryModel( m_pList[i].m_pCollisionModel );
}
}
delete[] m_pList;
}
int Count( void )
{
return m_listCount;
}
CPhysmesh *GetMesh( int index )
{
if ( index < m_listCount )
return m_pList + index;
return NULL;
}
float GetMass( void ) { return m_mass; }
void AddCollisionPair( int index0, int index1 )
{
collisionpair_t *pPair = new collisionpair_t;
pPair->object0 = index0;
pPair->object1 = index1;
pPair->pNext = m_pCollisionPairs;
m_pCollisionPairs = pPair;
}
void Load( MDLHandle_t handle );
char *DumpQC( void );
void ParseKeydata( void );
vcollide_t *GetVCollide()
{
return g_pMDLCache->GetVCollide( m_MDLHandle );
}
CPhysmesh *m_pList;
MDLHandle_t m_MDLHandle;
int m_listCount;
float m_mass;
editparams_t m_edit;
bool m_noselfCollisions;
collisionpair_t *m_pCollisionPairs;
};
void CPhysmesh::Clear( void )
{
memset( this, 0, sizeof(*this) );
memset( &m_constraint, 0, sizeof(m_constraint) );
m_constraint.parentIndex = -1;
m_constraint.childIndex = -1;
}
IStudioPhysics *LoadPhysics( MDLHandle_t mdlHandle )
{
CStudioPhysics *pPhysics = new CStudioPhysics;
pPhysics->Load( mdlHandle );
return pPhysics;
}
void DestroyPhysics( IStudioPhysics *pStudioPhysics )
{
CStudioPhysics *pPhysics = static_cast<CStudioPhysics*>( pStudioPhysics );
if ( pPhysics )
{
delete pPhysics;
}
}
void CStudioPhysics::Load( MDLHandle_t mdlHandle )
{
m_MDLHandle = mdlHandle;
LoadPhysicsProperties();
vcollide_t *pVCollide = GetVCollide( );
if ( !pVCollide )
{
m_pList = NULL;
m_listCount = 0;
return;
}
m_pList = new CPhysmesh[pVCollide->solidCount];
m_listCount = pVCollide->solidCount;
int i;
for ( i = 0; i < pVCollide->solidCount; i++ )
{
m_pList[i].Clear();
m_pList[i].m_vertCount = physcollision->CreateDebugMesh( pVCollide->solids[i], &m_pList[i].m_pVerts );
m_pList[i].m_pCollisionModel = physcollision->CreateQueryModel( pVCollide->solids[i] );
}
ParseKeydata();
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( mdlHandle ), g_pMDLCache );
for ( i = 0; i < pVCollide->solidCount; i++ )
{
CPhysmesh *pmesh = m_pList + i;
int boneIndex = FindBoneIndex( &studioHdr, pmesh->m_boneName );
if ( boneIndex < 0 )
continue;
if ( pmesh->m_constraint.parentIndex >= 0 )
{
CPhysmesh *pparent = m_pList + pmesh->m_constraint.parentIndex;
int parentIndex = FindBoneIndex( &studioHdr, pparent->m_boneName );
Studio_CalcBoneToBoneTransform( &studioHdr, boneIndex, parentIndex, pmesh->m_matrix );
}
else
{
MatrixInvert( studioHdr.pBone(boneIndex)->poseToBone, pmesh->m_matrix );
}
}
// doesn't have a root bone? Make it the first bone
if ( !m_edit.rootName[0] )
{
strcpy( m_edit.rootName, m_pList[0].m_boneName );
}
}
class CEditParse : public IVPhysicsKeyHandler
{
public:
virtual void ParseKeyValue( void *pCustom, const char *pKey, const char *pValue )
{
editparams_t *pEdit = (editparams_t *)pCustom;
if ( !strcmpi( pKey, "rootname" ) )
{
strncpy( pEdit->rootName, pValue, sizeof(pEdit->rootName) );
}
else if ( !strcmpi( pKey, "totalmass" ) )
{
pEdit->totalMass = atof( pValue );
}
else if ( !strcmpi( pKey, "concave" ) )
{
pEdit->concave = atoi( pValue );
}
else if ( !strcmpi( pKey, "jointmerge" ) )
{
char tmp[1024];
char parentName[512], childName[512];
Q_strncpy( tmp, pValue, 1024 );
char *pWord = strtok( tmp, "," );
Q_strncpy( parentName, pWord, sizeof(parentName) );
pWord = strtok( NULL, "," );
Q_strncpy( childName, pWord, sizeof(childName) );
if ( pEdit->mergeCount < ARRAYSIZE(pEdit->mergeList) )
{
merge_t *pMerge = &pEdit->mergeList[pEdit->mergeCount];
pEdit->mergeCount++;
pMerge->parent = g_pStudioModel->FindBone(parentName);
pMerge->child = g_pStudioModel->FindBone(childName);
}
}
}
virtual void SetDefaults( void *pCustom )
{
editparams_t *pEdit = (editparams_t *)pCustom;
memset( pEdit, 0, sizeof(*pEdit) );
}
};
class CRagdollCollisionRulesParse : public IVPhysicsKeyHandler
{
public:
CRagdollCollisionRulesParse( CStudioPhysics *pStudio ) : m_pStudio(pStudio)
{
pStudio->m_noselfCollisions = false;
}
virtual void ParseKeyValue( void *pData, const char *pKey, const char *pValue )
{
if ( !strcmpi( pKey, "selfcollisions" ) )
{
// keys disabled by default
Assert( atoi(pValue) == 0 );
m_pStudio->m_noselfCollisions = true;
}
else if ( !strcmpi( pKey, "collisionpair" ) )
{
if ( !m_pStudio->m_noselfCollisions )
{
char tmp[1024];
Q_strncpy( tmp, pValue, 1024 );
char *pWord = strtok( tmp, "," );
int index0 = atoi(pWord);
pWord = strtok( NULL, "," );
int index1 = atoi(pWord);
m_pStudio->AddCollisionPair( index0, index1 );
}
else
{
Assert(0);
}
}
}
virtual void SetDefaults( void *pData ) {}
private:
CStudioPhysics *m_pStudio;
};
class CSolidParse : public IVPhysicsKeyHandler
{
public:
virtual void ParseKeyValue( void *pCustom, const char *pKey, const char *pValue )
{
hlmvsolid_t *pSolid = (hlmvsolid_t *)pCustom;
if ( !strcmpi( pKey, "massbias" ) )
{
pSolid->massBias = atof( pValue );
}
else
{
printf("Bad key %s!!\n", pKey);
}
}
virtual void SetDefaults( void *pCustom )
{
hlmvsolid_t *pSolid = (hlmvsolid_t *)pCustom;
pSolid->massBias = 1.0;
}
};
void CStudioPhysics::ParseKeydata( void )
{
IVPhysicsKeyParser *pParser = physcollision->VPhysicsKeyParserCreate( GetVCollide()->pKeyValues );
while ( !pParser->Finished() )
{
const char *pBlock = pParser->GetCurrentBlockName();
if ( !stricmp( pBlock, "solid" ) )
{
hlmvsolid_t solid;
CSolidParse solidParse;
pParser->ParseSolid( &solid, &solidParse );
solid.surfacePropIndex = FindPhysprop( solid.surfaceprop );
if ( solid.index >= 0 && solid.index < m_listCount )
{
strcpy( m_pList[solid.index].m_boneName, solid.name );
memcpy( &m_pList[solid.index].m_solid, &solid, sizeof(solid) );
}
}
else if ( !stricmp( pBlock, "ragdollconstraint" ) )
{
constraint_ragdollparams_t constraint;
pParser->ParseRagdollConstraint( &constraint, NULL );
if ( constraint.childIndex >= 0 && constraint.childIndex < m_listCount )
{
// In the editor / qc these show up as 5X so that 1.0 is the default
constraint.axes[0].torque *= 5;
constraint.axes[1].torque *= 5;
constraint.axes[2].torque *= 5;
m_pList[constraint.childIndex].m_constraint = constraint;
}
}
else if ( !stricmp( pBlock, "editparams" ) )
{
CEditParse editParse;
pParser->ParseCustom( &m_edit, &editParse );
m_mass = m_edit.totalMass;
}
else if ( !strcmpi( pBlock, "collisionrules" ) )
{
CRagdollCollisionRulesParse rules(this);
pParser->ParseCustom( NULL, &rules );
}
else
{
pParser->SkipBlock();
}
}
physcollision->VPhysicsKeyParserDestroy( pParser );
}
int FindPhysprop( const char *pPropname )
{
if ( physprop )
{
int count = physprop->SurfacePropCount();
for ( int i = 0; i < count; i++ )
{
if ( !strcmpi( pPropname, physprop->GetPropName(i) ) )
return i;
}
}
return 0;
}
class CTextBuffer
{
public:
CTextBuffer( void ) {}
~CTextBuffer( void ) {}
inline int GetSize( void ) { return m_buffer.Size(); }
inline char *GetData( void ) { return m_buffer.Base(); }
void WriteText( const char *pText )
{
int len = strlen( pText );
CopyData( pText, len );
}
void Terminate( void ) { CopyData( "\0", 1 ); }
void CopyData( const char *pData, int len )
{
int offset = m_buffer.AddMultipleToTail( len );
memcpy( m_buffer.Base() + offset, pData, len );
}
private:
CUtlVector<char> m_buffer;
};
struct physdefaults_t
{
int surfacePropIndex;
float inertia;
float damping;
float rotdamping;
};
//-----------------------------------------------------------------------------
// Purpose: Nasty little routine (that was easy to code) to find the most common
// value in an array of structs containing that as a member
// Input : *pStructArray - pointer to head of struct array
// arrayCount - number of elements in the array
// structSize - size of each element
// fieldOffset - offset to the float we're finding
// Output : static T - most common value
//-----------------------------------------------------------------------------
template< class T >
static T FindCommonValue( void *pStructArray, int arrayCount, int structSize, int fieldOffset )
{
int maxCount = 0;
T maxVal = 0;
// BUGBUG: This is O(n^2), but n is really small
for ( int i = 0; i < arrayCount; i++ )
{
// current = struct[i].offset
T current = *(T *)((char *)pStructArray + (i*structSize) + fieldOffset);
int currentCount = 0;
// if everything is set to the default, this is almost O(n)
if ( current == maxVal )
continue;
for ( int j = 0; j < arrayCount; j++ )
{
// value = struct[j].offset
T value = *(T *)((char *)pStructArray + (j*structSize) + fieldOffset);
if ( value == current )
currentCount++;
}
if ( currentCount > maxCount )
{
maxVal = current;
maxCount = currentCount;
}
}
return maxVal;
}
static void CalcDefaultProperties( CPhysmesh *pList, int listCount, physdefaults_t &defs )
{
defs.surfacePropIndex = FindCommonValue<int>( pList, listCount, sizeof(CPhysmesh), offsetof(CPhysmesh, m_solid.surfacePropIndex) );
defs.inertia = FindCommonValue<float>( pList, listCount, sizeof(CPhysmesh), offsetof(CPhysmesh, m_solid.params.inertia) );
defs.damping = FindCommonValue<float>( pList, listCount, sizeof(CPhysmesh), offsetof(CPhysmesh, m_solid.params.damping) );
defs.rotdamping = FindCommonValue<float>( pList, listCount, sizeof(CPhysmesh), offsetof(CPhysmesh, m_solid.params.rotdamping) );
}
static void DumpModelProperties( CTextBuffer &out, float mass, physdefaults_t &defs )
{
char tmpbuf[1024];
sprintf( tmpbuf, "\t$mass %.1f\r\n", mass );
out.WriteText( tmpbuf );
sprintf( tmpbuf, "\t$inertia %.2f\r\n", defs.inertia );
out.WriteText( tmpbuf );
sprintf( tmpbuf, "\t$damping %.2f\r\n", defs.damping );
out.WriteText( tmpbuf );
sprintf( tmpbuf, "\t$rotdamping %.2f\r\n", defs.rotdamping );
out.WriteText( tmpbuf );
}
char *CStudioPhysics::DumpQC( void )
{
if ( !m_listCount )
return NULL;
CTextBuffer out;
physdefaults_t defs;
CalcDefaultProperties( m_pList, m_listCount, defs );
if ( m_listCount == 1 )
{
out.WriteText( "$collisionmodel ragdoll {\r\n\r\n" );
if ( m_edit.concave )
{
out.WriteText( "\t$concave\r\n" );
}
DumpModelProperties( out, m_mass, defs );
}
else
{
int i;
out.WriteText( "$collisionjoints ragdoll {\r\n\r\n" );
DumpModelProperties( out, m_mass, defs );
// write out the root bone
if ( m_edit.rootName[0] )
{
char tmp[128];
sprintf( tmp, "\t$rootbone \"%s\"\r\n", m_edit.rootName );
out.WriteText( tmp );
}
for ( i = 0; i < m_edit.mergeCount; i++ )
{
char tmp[1024];
if ( m_edit.mergeList[i].parent >= 0 && m_edit.mergeList[i].child >= 0 )
{
char const *pParentName = g_pStudioModel->GetStudioHdr()->pBone(m_edit.mergeList[i].parent)->pszName();
char const *pChildName = g_pStudioModel->GetStudioHdr()->pBone(m_edit.mergeList[i].child)->pszName();
Q_snprintf( tmp, sizeof(tmp), "\t$jointmerge \"%s\" \"%s\"\r\n", pParentName, pChildName );
out.WriteText( tmp );
}
}
char tmpbuf[1024];
for ( i = 0; i < m_listCount; i++ )
{
CPhysmesh *pmesh = m_pList + i;
char jointname[256];
sprintf( jointname, "\"%s\"", pmesh->m_boneName );
if ( pmesh->m_solid.massBias != 1.0 )
{
sprintf( tmpbuf, "\t$jointmassbias %s %.2f\r\n", jointname, pmesh->m_solid.massBias );
out.WriteText( tmpbuf );
}
if ( pmesh->m_solid.params.inertia != defs.inertia )
{
sprintf( tmpbuf, "\t$jointinertia %s %.2f\r\n", jointname, pmesh->m_solid.params.inertia );
out.WriteText( tmpbuf );
}
if ( pmesh->m_solid.params.damping != defs.damping )
{
sprintf( tmpbuf, "\t$jointdamping %s %.2f\r\n", jointname, pmesh->m_solid.params.damping );
out.WriteText( tmpbuf );
}
if ( pmesh->m_solid.params.rotdamping != defs.rotdamping )
{
sprintf( tmpbuf, "\t$jointrotdamping %s %.2f\r\n", jointname, pmesh->m_solid.params.rotdamping );
out.WriteText( tmpbuf );
}
if ( pmesh->m_constraint.parentIndex >= 0 )
{
for ( int j = 0; j < 3; j++ )
{
char *pAxis[] = { "x", "y", "z" };
sprintf( tmpbuf, "\t$jointconstrain %s %s limit %.2f %.2f %.2f\r\n", jointname, pAxis[j], pmesh->m_constraint.axes[j].minRotation, pmesh->m_constraint.axes[j].maxRotation, pmesh->m_constraint.axes[j].torque );
out.WriteText( tmpbuf );
}
}
if ( i != m_listCount-1 )
{
out.WriteText( "\r\n" );
}
}
}
if ( m_noselfCollisions )
{
out.WriteText( "\t$noselfcollisions\r\n" );
}
else if ( m_pCollisionPairs )
{
collisionpair_t *pPair = m_pCollisionPairs;
out.WriteText("\r\n");
while ( pPair )
{
out.WriteText( CFmtStr( "\t$jointcollide %s %s\r\n", m_pList[pPair->object0].m_boneName, m_pList[pPair->object1].m_boneName ) );
pPair = pPair->pNext;
}
}
out.WriteText( "}\r\n" );
// only need the pose for ragdolls
if ( m_listCount != 1 )
{
out.WriteText( "$sequence ragdoll \t\t\"ragdoll_pose\" \t\tFPS 30 \t\tactivity ACT_DIERAGDOLL 1\r\n" );
}
out.Terminate();
if ( out.GetSize() )
{
char *pOutput = new char[out.GetSize()];
memcpy( pOutput, out.GetData(), out.GetSize() );
return pOutput;
}
return NULL;
}
static const char *pMaterialFilename = "scripts/surfaceproperties.txt";
bool LoadPhysicsProperties( void )
{
// already loaded
if ( physprop->SurfacePropCount() )
return false;
FileHandle_t fp = g_pFileSystem->Open( pMaterialFilename, "rb" );
if ( fp == FILESYSTEM_INVALID_HANDLE )
return false;
int len = g_pFileSystem->Size( fp );
char *pText = new char[len+1];
g_pFileSystem->Read( pText, len, fp );
g_pFileSystem->Close( fp );
pText[len]=0;
physprop->ParseSurfaceData( pMaterialFilename, pText );
delete[] pText;
return true;
}

72
utils/hlmv/physmesh.h Normal file
View File

@@ -0,0 +1,72 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef PHYSMESH_H
#define PHYSMESH_H
#ifdef _WIN32
#pragma once
#endif
#include "datacache/imdlcache.h"
#include "vphysics_interface.h"
#include "vcollide_parse.h"
struct studiohdr_t;
struct hlmvsolid_t : public solid_t
{
float massBias;
int surfacePropIndex;
};
struct merge_t
{
int parent;
int child;
};
struct editparams_t
{
float totalMass;
char rootName[128];
int concave;
int mergeCount;
merge_t mergeList[32]; // there are never very many of these, so don't bother doing anything dynamic
};
class CPhysmesh
{
public:
void Clear( void );
char m_boneName[64];
int m_vertCount;
Vector *m_pVerts;
matrix3x4_t m_matrix;
hlmvsolid_t m_solid;
constraint_ragdollparams_t m_constraint;
ICollisionQuery *m_pCollisionModel;
};
class IStudioPhysics
{
public:
virtual ~IStudioPhysics( void ) {}
virtual char *DumpQC( void ) = 0;
virtual int Count( void ) = 0;
virtual CPhysmesh *GetMesh( int index ) = 0;
virtual float GetMass( void ) = 0;
};
IStudioPhysics *LoadPhysics( MDLHandle_t mdlHandle );
void DestroyPhysics( IStudioPhysics *pStudioPhysics );
#endif // PHYSMESH_H

23
utils/hlmv/resource.h Normal file
View File

@@ -0,0 +1,23 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by hlmviewer.rc
//
#define IDI_ICON1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,76 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include <string.h>
#include <assert.h>
#include "ViewerSettings.h"
#include "StudioModel.h"
#include "bitmap/TGALoader.h"
#include "materialsystem/imaterial.h"
#include "materialsystem/imaterialvar.h"
#include "materialsystem/itexture.h"
#include "matsyswin.h"
#include "istudiorender.h"
#include "studio_render.h"
Vector g_viewtarget( 0, 0, 0 );
float g_flexdescweight[MAXSTUDIOFLEXDESC];
float g_flexdescweight2[MAXSTUDIOFLEXDESC];
Vector vright( 1, 0, 0 );
Vector vup( 0, 1, 0 );
Vector r_origin( 0, 0, 0 );
// hack! Should probably use the gamma stuff in mathlib since we already linking it.
int LocalLinearToTexture( float v )
{
return pow( v, 1.0f / 2.2f ) * 255;
}
// hack! Should probably use the gamma stuff in mathlib since we already linking it.
float LocalTextureToLinear( int c )
{
return pow( c / 255.0, 2.2 );
}
#define sign( a ) (((a) < 0) ? -1 : (((a) > 0) ? 1 : 0 ))
void StudioModel::RunFlexRules( )
{
StudioModel *pSrcModel = g_pStudioModel;
// only the root model has control over flex rules
CStudioHdr *pSrcStudioHdr = pSrcModel->GetStudioHdr();
CStudioHdr *pDstStudioHdr = GetStudioHdr();
if ( !pSrcStudioHdr )
{
pSrcModel = this;
pSrcStudioHdr = GetStudioHdr();
}
float src[MAXSTUDIOFLEXCTRL*4];
for (LocalFlexController_t i = LocalFlexController_t(0); i < pSrcStudioHdr->numflexcontrollers(); i++)
{
mstudioflexcontroller_t *pflex = pSrcStudioHdr->pFlexcontroller( i );
int j = pSrcStudioHdr->pFlexcontroller( i )->localToGlobal;
// remap m_flexweights to full dynamic range, global flexcontroller indexes
if (j >= 0 && j < MAXSTUDIOFLEXCTRL*4)
{
src[j] = pSrcModel->m_flexweight[i] * (pflex->max - pflex->min) + pflex->min;
}
}
pDstStudioHdr->RunFlexRules( src, g_flexdescweight );
}

2368
utils/hlmv/studio_render.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef STUDIO_RENDER_H
#define STUDIO_RENDER_H
#ifdef _WIN32
#pragma once
#endif
extern Vector g_viewtarget;
extern Vector g_flexedverts[];
extern Vector g_flexednorms[];
extern int g_flexages[];
extern DrawModelInfo_t g_DrawModelInfo;
extern DrawModelResults_t g_DrawModelResults;
extern bool g_bDrawModelInfoValid;
#endif // STUDIO_RENDER_H

1224
utils/hlmv/studio_utils.cpp Normal file

File diff suppressed because it is too large Load Diff

483
utils/hlmv/studiomodel.h Normal file
View File

@@ -0,0 +1,483 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef INCLUDED_STUDIOMODEL
#define INCLUDED_STUDIOMODEL
#include "mathlib/mathlib.h"
#include "studio.h"
#include "mouthinfo.h"
#include "UtlLinkedList.h"
#include "utlsymbol.h"
#include "bone_setup.h"
#include "datacache/imdlcache.h"
#include "viewersettings.h"
#include "tier1/utlstring.h"
#define DEFAULT_BLEND_TIME 0.2
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
typedef struct IFACE_TAG IFACE;
typedef struct IMESH_TAG IMESH;
typedef struct ResolutionUpdateTag ResolutionUpdate;
typedef struct FaceUpdateTag FaceUpdate;
class IMaterial;
class IDataCache;
class IStudioPhysics;
class IMaterialSystem;
class IMDLCache;
class CPhysmesh;
struct hlmvsolid_t;
struct constraint_ragdollparams_t;
class IStudioRender;
class IPhysicsSurfaceProps;
class IPhysicsCollision;
class IStudioDataCache;
class IDataCache;
class IFileSystem;
class IMaterialSystemHardwareConfig;
class CJiggleBones;
//-----------------------------------------------------------------------------
// Singleton interfaces
//-----------------------------------------------------------------------------
extern IStudioRender *g_pStudioRender;
extern IMDLCache *g_pMDLCache;
extern IPhysicsSurfaceProps *physprop;
extern IPhysicsCollision *physcollision;
extern IStudioDataCache *g_pStudioDataCache;
extern IDataCache *g_pDataCache;
extern IFileSystem *g_pFileSystem;
extern IMaterialSystem *g_pMaterialSystem;
extern IMaterialSystemHardwareConfig *g_pMaterialSystemHardwareConfig;
class AnimationLayer
{
public:
float m_cycle; // 0 to 1 animation playback index
int m_sequence; // sequence index
float m_weight;
float m_playbackrate;
int m_priority; // lower priorities get layered first
};
struct StudioLookTarget
{
float m_flWeight;
Vector m_vecPosition;
bool m_bSelf;
};
struct HitboxInfo_t
{
CUtlString m_Name;
mstudiobbox_t m_BBox;
};
// I'm saving this as internal data because we may add or remove hitboxes
// I'm using a utllinkedlist so hitbox IDs remain constant on add + remove
typedef CUtlLinkedList< HitboxInfo_t, unsigned short > HitboxList_t;
struct HitboxSet_t
{
CUtlString m_Name;
HitboxList_t m_Hitboxes;
};
class StudioModel
{
public:
StudioModel();
// memory handling, uses calloc so members are zero'd out on instantiation
static void *operator new( size_t nSize );
static void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine );
static void operator delete( void *pData );
static void operator delete( void* p, int nBlockUse, const char *pFileName, int nLine );
static void Init( void );
static void Shutdown( void ); // garymcthack - need to call this.
static void UpdateViewState( const Vector& viewOrigin,
const Vector& viewRight,
const Vector& viewUp,
const Vector& viewPlaneNormal );
static void ReleaseStudioModel( void );
static void RestoreStudioModel( void );
static void UnloadGroupFiles();
char const *GetFileName( void );
IStudioRender *GetStudioRender();
static void UpdateStudioRenderConfig( bool bWireframe, bool bZBufferWireframe, bool bNormals, bool bTangentFrame );
studiohdr_t *getAnimHeader (int i) const;
virtual void ModelInit( void ) { }
bool IsModelLoaded() const;
void FreeModel( bool bReleasing );
bool LoadModel( const char *modelname );
virtual bool PostLoadModel ( const char *modelname );
bool HasModel();
virtual int DrawModel( bool mergeBones = false );
virtual void AdvanceFrame( float dt );
float GetInterval( void );
float GetCycle( void );
float GetFrame( void );
int GetMaxFrame( void );
int SetFrame( int frame );
float GetCycle( int iLayer );
float GetFrame( int iLayer );
int GetMaxFrame( int iLayer );
int SetFrame( int iLayer, int frame );
void ExtractBbox( Vector &mins, Vector &maxs );
void SetBlendTime( float blendtime );
int LookupSequence( const char *szSequence );
int LookupActivity( const char *szActivity );
int SetSequence( int iSequence );
int SetSequence( const char *szSequence );
const char* GetSequenceName( int iSequence );
void ClearOverlaysSequences( void );
void ClearAnimationLayers( void );
int GetNewAnimationLayer( int iPriority = 0 );
int SetOverlaySequence( int iLayer, int iSequence, float flWeight );
float SetOverlayRate( int iLayer, float flCycle, float flFrameRate );
int GetOverlaySequence( int iLayer );
float GetOverlaySequenceWeight( int iLayer );
void StartBlending( void );
float GetTransitionAmount( void );
int GetSequence( void );
void GetSequenceInfo( int iSequence, float *pflFrameRate, float *pflGroundSpeed );
void GetSequenceInfo( float *pflFrameRate, float *pflGroundSpeed );
float GetFPS( int iSequence );
float GetFPS( );
float GetDuration( int iSequence );
float GetDuration( );
int GetNumFrames( int iSequence );
bool GetSequenceLoops( int iSequence );
void GetMovement( float prevCycle[5], Vector &vecPos, QAngle &vecAngles );
void GetMovement( int iSequence, float prevCycle, float currCycle, Vector &vecPos, QAngle &vecAngles );
void GetSeqAnims( int iSequence, mstudioanimdesc_t *panim[4], float *pweights );
void GetSeqAnims( mstudioanimdesc_t *panim[4], float *pweights );
float GetGroundSpeed( int iSequence );
float GetGroundSpeed( void );
float GetCurrentVelocity( void );
bool IsHidden( int iSequence );
float SetController( int iController, float flValue );
int LookupPoseParameter( char const *szName );
float SetPoseParameter( int iParameter, float flValue );
float SetPoseParameter( char const *szName, float flValue );
float GetPoseParameter( char const *szName );
float GetPoseParameter( int iParameter );
bool GetPoseParameterRange( int iParameter, float *pflMin, float *pflMax );
float* GetPoseParameters();
int LookupAttachment( char const *szName );
int SetBodygroup( int iGroup, int iValue = -1 );
int SetSkin( int iValue );
int FindBone( const char *pName );
LocalFlexController_t LookupFlexController( char *szName );
void SetFlexController( char *szName, float flValue );
void SetFlexController( LocalFlexController_t iFlex, float flValue );
float GetFlexController( char *szName );
float GetFlexController( LocalFlexController_t iFlex );
void SetFlexControllerRaw( LocalFlexController_t iFlex, float flValue );
float GetFlexControllerRaw( LocalFlexController_t iFlex );
// void CalcBoneTransform( int iBone, Vector pos[], Quaternion q[], matrix3x4_t& bonematrix );
void UpdateBoneChain( Vector pos[], Quaternion q[], int iBone, matrix3x4_t *pBoneToWorld );
void SetViewTarget( void ); // ???
void GetBodyPoseParametersFromFlex( void );
void CalcHeadRotation( Vector pos[], Quaternion q[] );
float SetHeadPosition( matrix3x4_t& attToWorld, Vector const &vTargetPos, float dt );
int GetNumLODs() const;
float GetLODSwitchValue( int lod ) const;
void SetLODSwitchValue( int lod, float switchValue );
void scaleMeshes( float scale );
void scaleBones( float scale );
// Physics
void OverrideBones( bool *override );
int Physics_GetBoneCount( void );
const char * Physics_GetBoneName( int index );
int Physics_GetBoneIndex( const char *pName );
void Physics_GetData( int boneIndex, hlmvsolid_t *psolid, constraint_ragdollparams_t *pConstraint ) const;
void Physics_SetData( int boneIndex, const hlmvsolid_t *psolid, constraint_ragdollparams_t const *pConstraint );
void Physics_SetPreview( int previewBone, int axis, float t );
float Physics_GetMass( void );
void Physics_SetMass( float mass );
char *Physics_DumpQC( void );
float GetSequenceTime() const { return m_sequencetime; }
float GetTimeDelta() const { return m_dt; }
CStudioHdr *m_pStudioHdr;
CStudioHdr *GetStudioHdr() const;
studiohdr_t *GetStudioRenderHdr() const;
studiohwdata_t *GetHardwareData( void ) const;
// Get and set the model transform (i.e. what m_origin and m_angles are used to generate).
void GetModelTransform( matrix3x4_t &mat );
void SetModelTransform( const matrix3x4_t &mat );
public:
// entity settings
QAngle m_angles; // rot
Vector m_origin; // trans
protected:
int m_bodynum; // bodypart selection
int m_skinnum; // skin group selection
float m_controller[4]; // bone controllers
public:
CMouthInfo m_mouth;
protected:
char *m_pModelName; // model file name
// bool m_owntexmodel; // do we have a modelT.mdl ?
// Previouse sequence data
float m_blendtime;
float m_sequencetime;
int m_prevsequence;
float m_prevcycle;
float m_dt;
// Blending info
// Gesture,Sequence layering state
#define MAXSTUDIOANIMLAYERS 8
AnimationLayer m_Layer[MAXSTUDIOANIMLAYERS];
int m_iActiveLayers;
public:
float m_cycle; // 0 to 1 animation playback index
protected:
int m_sequence; // sequence index
float m_poseparameter[MAXSTUDIOPOSEPARAM]; // intra-sequence blending
float m_weight;
// internal data
MDLHandle_t m_MDLHandle;
mstudiomodel_t *m_pmodel;
public:
CUtlVector< HitboxSet_t > m_HitboxSets;
CUtlVector< CUtlSymbol > m_SurfaceProps;
protected:
// class data
static Vector *m_AmbientLightColors;
// Added data
// IMESH *m_pimesh;
// VertexUpdate *m_pvertupdate;
// FaceUpdate *m_pfaceupdate;
IFACE *m_pface;
// studiohdr_t *m_ptexturehdr;
Vector4D m_adj; // FIX: non persistant, make static
public:
IStudioPhysics *m_pPhysics;
private:
int m_physPreviewBone;
int m_physPreviewAxis;
float m_physPreviewParam;
float m_physMass;
public:
mstudioseqdesc_t &GetSeqDesc( int seq );
const matrix3x4_t* BoneToWorld( int nBoneIndex ) const;
private:
mstudioanimdesc_t &GetAnimDesc( int anim );
mstudioanim_t *GetAnim( int anim );
void DrawPhysmesh( CPhysmesh *pMesh, int boneIndex, IMaterial *pMaterial, float *color );
void DrawPhysConvex( CPhysmesh *pMesh, IMaterial *pMaterial );
void SetupLighting( void );
virtual void SetupModel( int bodypart );
private:
float m_flexweight[MAXSTUDIOFLEXCTRL];
matrix3x4_t m_pBoneToWorld[MAXSTUDIOBONES];
public:
virtual void RunFlexRules( void );
virtual int BoneMask( void );
virtual void SetUpBones( bool mergeBones );
int GetLodUsed( void );
float GetLodMetric( void );
const char *GetKeyValueText( int iSequence );
private:
// Drawing helper methods
void DrawBones( );
void DrawAttachments( );
void DrawEditAttachment();
void DrawHitboxes();
void DrawPhysicsModel( );
void DrawIllumPosition( );
void DrawOriginAxis( );
public:
// generic interface to rendering?
void drawBox (Vector const *v, float const * color );
void drawWireframeBox (Vector const *v, float const* color );
void drawTransform( matrix3x4_t& m, float flLength = 4 );
void drawLine( Vector const &p1, Vector const &p2, int r = 0, int g = 0, int b = 255 );
void drawTransparentBox( Vector const &bbmin, Vector const &bbmax, const matrix3x4_t& m, float const *color, float const *wirecolor );
private:
int m_LodUsed;
float m_LodMetric;
public:
void SetSolveHeadTurn( int solve );
int GetSolveHeadTurn() const;
void ClearLookTargets( void );
void AddLookTarget( const Vector& vecPosition, float flWeight );
void AddLookTargetSelf( float flWeight );
void SetModelYaw( float yaw );
float GetModelYaw( void ) const;
void SetBodyYaw( float yaw );
float GetBodyYaw( void ) const;
void SetSpineYaw( float yaw );
float GetSpineYaw( void ) const;
private:
// 0 == no, 1 == based on dt, 2 == completely.
int m_nSolveHeadTurn;
CUtlVector < StudioLookTarget > m_vecHeadTargets;
float m_flModelYaw;
float m_flBodyYaw;
float m_flSpineYaw;
public:
bool m_bIsTransparent;
bool m_bHasProxy;
// necessary for accessing correct vertexes
void SetCurrentModel();
public:
CIKContext m_ik;
float m_prevGroundCycles[5];
float m_prevIKCycles[5];
public:
void IncrementFramecounter( void ) { m_iFramecounter++; };
private:
int m_iFramecounter;
private:
CJiggleBones *m_pJiggleBones;
};
//-----------------------------------------------------------------------------
// Inline methods
//-----------------------------------------------------------------------------
inline CStudioHdr *StudioModel::GetStudioHdr( void ) const
{
if (!m_pStudioHdr || m_pStudioHdr->IsReadyForAccess())
return m_pStudioHdr;
studiohdr_t *hdr = g_pMDLCache->GetStudioHdr( m_MDLHandle );
m_pStudioHdr->Init( hdr );
if (m_pStudioHdr->IsReadyForAccess())
return m_pStudioHdr;
return NULL;
}
inline studiohdr_t *StudioModel::GetStudioRenderHdr( void ) const
{
return g_pMDLCache->GetStudioHdr( m_MDLHandle );
}
inline studiohwdata_t *StudioModel::GetHardwareData( void ) const
{
return g_pMDLCache->GetHardwareData( m_MDLHandle );
}
inline studiohdr_t *StudioModel::getAnimHeader( int i ) const
{
// return g_pMDLCache->GetStudioHdr( m_AnimHandle[i] );
// return m_panimhdr[i];
}
inline char const *StudioModel::GetFileName( void )
{
return m_pModelName;
}
inline IStudioRender *StudioModel::GetStudioRender()
{
return g_pStudioRender;
}
inline bool StudioModel::IsModelLoaded() const
{
return m_MDLHandle != MDLHANDLE_INVALID;
}
inline const matrix3x4_t* StudioModel::BoneToWorld( int nBoneIndex ) const
{
return &m_pBoneToWorld[nBoneIndex];
}
//-----------------------------------------------------------------------------
// Globals
//-----------------------------------------------------------------------------
extern Vector g_vright; // needs to be set to viewer's right in order for chrome to work
extern StudioModel *g_pStudioModel;
extern StudioModel *g_pStudioExtraModel[HLMV_MAX_MERGED_MODELS];
#endif // INCLUDED_STUDIOMODEL

14
utils/hlmv/sys.h Normal file
View File

@@ -0,0 +1,14 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef SYS_H
#define SYS_H
#pragma once
extern void Sys_CopyStringToClipboard( const char *pOut );
#endif // SYS_H

37
utils/hlmv/sys_win.cpp Normal file
View File

@@ -0,0 +1,37 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: abstract system dependent functions
//
// $NoKeywords: $
//=============================================================================//
#include "sys.h"
#include <windows.h>
#include "tier1/strtools.h"
void Sys_CopyStringToClipboard( const char *pOut )
{
if ( !pOut || !OpenClipboard( NULL ) )
{
return;
}
// Remove the current Clipboard contents
if( !EmptyClipboard() )
{
return;
}
HGLOBAL clipbuffer;
char *buffer;
EmptyClipboard();
int len = Q_strlen(pOut)+1;
clipbuffer = GlobalAlloc(GMEM_DDESHARE, len );
buffer = (char*)GlobalLock( clipbuffer );
Q_strncpy( buffer, pOut, len );
GlobalUnlock( clipbuffer );
SetClipboardData( CF_TEXT,clipbuffer );
CloseClipboard();
}

View File

@@ -0,0 +1,704 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
//
// Half-Life Model Viewer (c) 1999 by Mete Ciragan
//
// file: ViewerSettings.cpp
// last modified: May 29 1999, Mete Ciragan
// copyright: The programs and associated files contained in this
// distribution were developed by Mete Ciragan. The programs
// are not in the public domain, but they are freely
// distributable without licensing fees. These programs are
// provided without guarantee or warrantee expressed or
// implied.
//
// version: 1.2
//
// email: mete@swissquake.ch
// web: http://www.swissquake.ch/chumbalum-soft/
//
#include "ViewerSettings.h"
#include "studiomodel.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "windows.h"
ViewerSettings g_viewerSettings;
ViewerSettings::ViewerSettings()
{
Q_memset( this, 0, sizeof( *this ) );
}
void InitViewerSettings ( const char *subkey )
{
ViewerSettings save = g_viewerSettings;
memset (&g_viewerSettings, 0, sizeof (ViewerSettings));
// Some values should survive. This is a crappy way to do settings in general. Sigh.
{
g_viewerSettings.faceposerToolsDriveMouth = save.faceposerToolsDriveMouth;
}
strcpy( g_viewerSettings.registrysubkey, subkey );
g_pStudioModel->m_angles.Init( -90.0f, 0.0f, 0.0f );
g_pStudioModel->m_origin.Init( 0.0f, 0.0f, 50.0f );
g_viewerSettings.renderMode = RM_TEXTURED;
g_viewerSettings.fov = 65.0f;
g_viewerSettings.enableNormalMapping = true;
g_viewerSettings.enableParallaxMapping = false;
g_viewerSettings.showNormals = false;
g_viewerSettings.showTangentFrame = false;
g_viewerSettings.overlayWireframe = false;
g_viewerSettings.enableSpecular = true;
g_viewerSettings.playSounds = true;
g_viewerSettings.bgColor[0] = 0.25f;
g_viewerSettings.bgColor[1] = 0.25f;
g_viewerSettings.bgColor[2] = 0.25f;
g_viewerSettings.gColor[0] = 0.85f;
g_viewerSettings.gColor[1] = 0.85f;
g_viewerSettings.gColor[2] = 0.69f;
g_viewerSettings.lColor[0] = 1.0f;
g_viewerSettings.lColor[1] = 1.0f;
g_viewerSettings.lColor[2] = 1.0f;
g_viewerSettings.aColor[0] = 0.3f;
g_viewerSettings.aColor[1] = 0.3f;
g_viewerSettings.aColor[2] = 0.3f;
g_viewerSettings.lightrot[0] = 0.0f;
g_viewerSettings.lightrot[1] = 180.0f;
g_viewerSettings.lightrot[2] = 0.0f;
g_viewerSettings.speedScale = 1.0f;
g_viewerSettings.application_mode = 0;
g_viewerSettings.thumbnailsize = 128;
g_viewerSettings.thumbnailsizeanim = 128;
g_viewerSettings.m_iEditAttachment = -1;
g_viewerSettings.highlightHitbox = -1;
g_viewerSettings.highlightBone = -1;
g_viewerSettings.speechapiindex = 0;
g_viewerSettings.cclanguageid = 0;
// default hlmv settings
g_viewerSettings.xpos = 20;
g_viewerSettings.ypos = 20;
g_viewerSettings.width = 640;
g_viewerSettings.height = 700;
g_viewerSettings.originAxisLength = 10.0f;
}
bool RegReadVector( HKEY hKey, const char *szSubKey, Vector& value )
{
LONG lResult; // Registry function result code
char szBuff[128]; // Temp. buffer
DWORD dwType; // Type of key
DWORD dwSize; // Size of element data
dwSize = sizeof( szBuff );
lResult = RegQueryValueEx(
hKey, // handle to key
szSubKey, // value name
0, // reserved
&dwType, // type buffer
(LPBYTE)szBuff, // data buffer
&dwSize ); // size of data buffer
if (lResult != ERROR_SUCCESS) // Failure
return false;
if (sscanf( szBuff, "(%f %f %f)", &value[0], &value[1], &value[2] ) != 3)
return false;
return true;
}
bool RegReadQAngle( HKEY hKey, const char *szSubKey, QAngle& value )
{
Vector tmp;
if (RegReadVector( hKey, szSubKey, tmp ))
{
value.Init( tmp.x, tmp.y, tmp.z );
return true;
}
return false;
}
bool RegReadColor( HKEY hKey, const char *szSubKey, float value[4] )
{
LONG lResult; // Registry function result code
char szBuff[128]; // Temp. buffer
DWORD dwType; // Type of key
DWORD dwSize; // Size of element data
dwSize = sizeof( szBuff );
lResult = RegQueryValueEx(
hKey, // handle to key
szSubKey, // value name
0, // reserved
&dwType, // type buffer
(LPBYTE)szBuff, // data buffer
&dwSize ); // size of data buffer
if (lResult != ERROR_SUCCESS) // Failure
return false;
if (sscanf( szBuff, "(%f %f %f %f)", &value[0], &value[1], &value[2], &value[3] ) != 4)
return false;
return true;
}
bool RegWriteVector( HKEY hKey, const char *szSubKey, Vector& value )
{
LONG lResult; // Registry function result code
char szBuff[128]; // Temp. buffer
DWORD dwSize; // Size of element data
sprintf( szBuff, "(%f %f %f)", value[0], value[1], value[2] );
dwSize = strlen( szBuff );
lResult = RegSetValueEx(
hKey, // handle to key
szSubKey, // value name
0, // reserved
REG_SZ, // type buffer
(LPBYTE)szBuff, // data buffer
dwSize ); // size of data buffer
if (lResult != ERROR_SUCCESS) // Failure
return false;
return true;
}
bool RegWriteQAngle( HKEY hKey, const char *szSubKey, QAngle& value )
{
Vector tmp;
tmp.Init( value.x, value.y, value.z );
return RegWriteVector( hKey, szSubKey, tmp );
}
bool RegWriteColor( HKEY hKey, const char *szSubKey, float value[4] )
{
LONG lResult; // Registry function result code
char szBuff[128]; // Temp. buffer
DWORD dwSize; // Size of element data
sprintf( szBuff, "(%f %f %f %f)", value[0], value[1], value[2], value[3] );
dwSize = strlen( szBuff );
lResult = RegSetValueEx(
hKey, // handle to key
szSubKey, // value name
0, // reserved
REG_SZ, // type buffer
(LPBYTE)szBuff, // data buffer
dwSize ); // size of data buffer
if (lResult != ERROR_SUCCESS) // Failure
return false;
return true;
}
bool RegReadBool( HKEY hKey, const char *szSubKey, bool *value )
{
LONG lResult; // Registry function result code
DWORD dwType; // Type of key
DWORD dwSize; // Size of element data
DWORD dwTemp;
dwSize = sizeof( dwTemp );
lResult = RegQueryValueEx(
hKey, // handle to key
szSubKey, // value name
0, // reserved
&dwType, // type buffer
(LPBYTE)&dwTemp, // data buffer
&dwSize ); // size of data buffer
if (lResult != ERROR_SUCCESS) // Failure
return false;
if (dwType != REG_DWORD)
return false;
*value = (dwTemp != 0);
return true;
}
bool RegReadInt( HKEY hKey, const char *szSubKey, int *value )
{
LONG lResult; // Registry function result code
DWORD dwType; // Type of key
DWORD dwSize; // Size of element data
dwSize = sizeof( DWORD );
lResult = RegQueryValueEx(
hKey, // handle to key
szSubKey, // value name
0, // reserved
&dwType, // type buffer
(LPBYTE)value, // data buffer
&dwSize ); // size of data buffer
if (lResult != ERROR_SUCCESS) // Failure
return false;
if (dwType != REG_DWORD)
return false;
return true;
}
bool RegWriteInt( HKEY hKey, const char *szSubKey, int value )
{
LONG lResult; // Registry function result code
DWORD dwSize; // Size of element data
dwSize = sizeof( DWORD );
lResult = RegSetValueEx(
hKey, // handle to key
szSubKey, // value name
0, // reserved
REG_DWORD, // type buffer
(LPBYTE)&value, // data buffer
dwSize ); // size of data buffer
if (lResult != ERROR_SUCCESS) // Failure
return false;
return true;
}
bool RegReadFloat( HKEY hKey, const char *szSubKey, float *value )
{
LONG lResult; // Registry function result code
char szBuff[128]; // Temp. buffer
DWORD dwType; // Type of key
DWORD dwSize; // Size of element data
dwSize = sizeof( szBuff );
lResult = RegQueryValueEx(
hKey, // handle to key
szSubKey, // value name
0, // reserved
&dwType, // type buffer
(LPBYTE)szBuff, // data buffer
&dwSize ); // size of data buffer
if (lResult != ERROR_SUCCESS) // Failure
return false;
*value = atof( szBuff );
return true;
}
bool RegWriteFloat( HKEY hKey, const char *szSubKey, float value )
{
LONG lResult; // Registry function result code
char szBuff[128]; // Temp. buffer
DWORD dwSize; // Size of element data
sprintf( szBuff, "%f", value );
dwSize = strlen( szBuff );
lResult = RegSetValueEx(
hKey, // handle to key
szSubKey, // value name
0, // reserved
REG_SZ, // type buffer
(LPBYTE)szBuff, // data buffer
dwSize ); // size of data buffer
if (lResult != ERROR_SUCCESS) // Failure
return false;
return true;
}
bool RegReadString( HKEY hKey, const char *szSubKey, char *string, int size )
{
LONG lResult; // Registry function result code
DWORD dwType; // Type of key
DWORD dwSize; // Size of element data
dwSize = size;
lResult = RegQueryValueEx(
hKey, // handle to key
szSubKey, // value name
0, // reserved
&dwType, // type buffer
(LPBYTE)string, // data buffer
&dwSize ); // size of data buffer
if (lResult != ERROR_SUCCESS) // Failure
return false;
if (dwType != REG_SZ)
return false;
return true;
}
bool RegWriteString( HKEY hKey, const char *szSubKey, char *string )
{
LONG lResult; // Registry function result code
DWORD dwSize; // Size of element data
dwSize = strlen( string );
lResult = RegSetValueEx(
hKey, // handle to key
szSubKey, // value name
0, // reserved
REG_SZ, // type buffer
(LPBYTE)string, // data buffer
dwSize ); // size of data buffer
if (lResult != ERROR_SUCCESS) // Failure
return false;
return true;
}
LONG RegViewerSettingsKey( const char *filename, PHKEY phKey, LPDWORD lpdwDisposition )
{
if (strlen( filename ) == 0)
return ERROR_KEY_DELETED;
char szFileName[1024];
strcpy( szFileName, filename );
// strip out bogus characters
for (char *cp = szFileName; *cp; cp++)
{
if (*cp == '\\' || *cp == '/' || *cp == ':')
*cp = '.';
}
char szModelKey[1024];
sprintf( szModelKey, "Software\\Valve\\%s\\%s", g_viewerSettings.registrysubkey, szFileName );
return RegCreateKeyEx(
HKEY_CURRENT_USER, // handle of open key
szModelKey, // address of name of subkey to open
0, // DWORD ulOptions, // reserved
NULL, // Type of value
REG_OPTION_NON_VOLATILE, // Store permanently in reg.
KEY_ALL_ACCESS, // REGSAM samDesired, // security access mask
NULL,
phKey, // Key we are creating
lpdwDisposition); // Type of creation
}
LONG RegViewerRootKey( PHKEY phKey, LPDWORD lpdwDisposition )
{
char szRootKey[1024];
sprintf( szRootKey, "Software\\Valve\\%s", g_viewerSettings.registrysubkey );
return RegCreateKeyEx(
HKEY_CURRENT_USER, // handle of open key
szRootKey, // address of name of subkey to open
0, // DWORD ulOptions, // reserved
NULL, // Type of value
REG_OPTION_NON_VOLATILE, // Store permanently in reg.
KEY_ALL_ACCESS, // REGSAM samDesired, // security access mask
NULL,
phKey, // Key we are creating
lpdwDisposition); // Type of creation
}
bool LoadViewerSettingsInt( char const *keyname, int *value )
{
LONG lResult; // Registry function result code
DWORD dwDisposition; // Type of key opening event
HKEY hModelKey;
lResult = RegViewerSettingsKey( "hlfaceposer", &hModelKey, &dwDisposition);
if (lResult != ERROR_SUCCESS) // Failure
return false;
// First time, just set to Valve default
if (dwDisposition == REG_CREATED_NEW_KEY)
{
return false;
}
*value = 0;
RegReadInt( hModelKey, keyname, value );
return true;
}
bool SaveViewerSettingsInt ( const char *keyname, int value )
{
LONG lResult; // Registry function result code
DWORD dwDisposition; // Type of key opening event
HKEY hModelKey;
lResult = RegViewerSettingsKey( "hlfaceposer", &hModelKey, &dwDisposition);
if (lResult != ERROR_SUCCESS) // Failure
return false;
RegWriteInt( hModelKey, keyname, value );
return true;
}
bool LoadViewerSettings (const char *filename, StudioModel *pModel )
{
LONG lResult; // Registry function result code
DWORD dwDisposition; // Type of key opening event
HKEY hModelKey;
if (filename == NULL || pModel == NULL)
return false;
lResult = RegViewerSettingsKey( filename, &hModelKey, &dwDisposition);
if (lResult != ERROR_SUCCESS) // Failure
return false;
// First time, just set to Valve default
if (dwDisposition == REG_CREATED_NEW_KEY)
{
return false;
}
RegReadQAngle( hModelKey, "Rot", pModel->m_angles );
RegReadVector( hModelKey, "Trans", pModel->m_origin );
RegReadColor( hModelKey, "bgColor", g_viewerSettings.bgColor );
RegReadColor( hModelKey, "gColor", g_viewerSettings.gColor );
RegReadColor( hModelKey, "lColor", g_viewerSettings.lColor );
RegReadColor( hModelKey, "aColor", g_viewerSettings.aColor );
RegReadQAngle( hModelKey, "lightrot", g_viewerSettings.lightrot );
int iTemp;
float flTemp;
char szTemp[256];
RegReadString( hModelKey, "sequence", szTemp, sizeof( szTemp ) );
iTemp = pModel->LookupSequence( szTemp );
pModel->SetSequence( iTemp );
RegReadString( hModelKey, "overlaySequence0", szTemp, sizeof( szTemp ) );
iTemp = pModel->LookupSequence( szTemp );
RegReadFloat( hModelKey, "overlayWeight0", &flTemp );
pModel->SetOverlaySequence( 0, iTemp, flTemp );
RegReadString( hModelKey, "overlaySequence1", szTemp, sizeof( szTemp ) );
iTemp = pModel->LookupSequence( szTemp );
RegReadFloat( hModelKey, "overlayWeight1", &flTemp );
pModel->SetOverlaySequence( 1, iTemp, flTemp );
RegReadString( hModelKey, "overlaySequence2", szTemp, sizeof( szTemp ) );
iTemp = pModel->LookupSequence( szTemp );
RegReadFloat( hModelKey, "overlayWeight2", &flTemp );
pModel->SetOverlaySequence( 2, iTemp, flTemp );
RegReadString( hModelKey, "overlaySequence3", szTemp, sizeof( szTemp ) );
iTemp = pModel->LookupSequence( szTemp );
RegReadFloat( hModelKey, "overlayWeight3",&flTemp );
pModel->SetOverlaySequence( 3, iTemp, flTemp );
RegReadFloat( hModelKey, "speedscale", &g_viewerSettings.speedScale );
if (g_viewerSettings.speedScale > 1.0)
g_viewerSettings.speedScale = 1.0;
RegReadInt( hModelKey, "viewermode", &g_viewerSettings.application_mode );
RegReadInt( hModelKey, "thumbnailsize", &g_viewerSettings.thumbnailsize );
RegReadInt( hModelKey, "thumbnailsizeanim", &g_viewerSettings.thumbnailsizeanim );
if ( g_viewerSettings.thumbnailsize == 0 )
{
g_viewerSettings.thumbnailsize = 128;
}
if ( g_viewerSettings.thumbnailsizeanim == 0 )
{
g_viewerSettings.thumbnailsizeanim = 128;
}
RegReadInt( hModelKey, "speechapiindex", &g_viewerSettings.speechapiindex );
RegReadInt( hModelKey, "cclanguageid", &g_viewerSettings.cclanguageid );
RegReadBool( hModelKey, "showground", &g_viewerSettings.showGround );
RegReadBool( hModelKey, "showbackground", &g_viewerSettings.showBackground );
RegReadBool( hModelKey, "showshadow", &g_viewerSettings.showShadow );
RegReadBool( hModelKey, "showillumpos", &g_viewerSettings.showIllumPosition );
RegReadBool( hModelKey, "enablenormalmapping", &g_viewerSettings.enableNormalMapping );
RegReadBool( hModelKey, "playsounds", &g_viewerSettings.playSounds );
RegReadBool( hModelKey, "showoriginaxis", &g_viewerSettings.showOriginAxis );
RegReadFloat( hModelKey, "originaxislength", &g_viewerSettings.originAxisLength );
char merge_buffer[32];
for ( int i = 0; i < HLMV_MAX_MERGED_MODELS; i++ )
{
Q_snprintf( merge_buffer, sizeof( merge_buffer ), "merge%d", i + 1 );
RegReadString( hModelKey, merge_buffer, g_viewerSettings.mergeModelFile[i], sizeof( g_viewerSettings.mergeModelFile[i] ) );
}
return true;
}
bool LoadViewerRootSettings( void )
{
LONG lResult; // Registry function result code
DWORD dwDisposition; // Type of key opening event
HKEY hRootKey;
lResult = RegViewerRootKey( &hRootKey, &dwDisposition);
if (lResult != ERROR_SUCCESS) // Failure
return false;
RegReadInt( hRootKey, "renderxpos", &g_viewerSettings.xpos );
RegReadInt( hRootKey, "renderypos", &g_viewerSettings.ypos );
RegReadInt( hRootKey, "renderwidth", &g_viewerSettings.width );
RegReadInt( hRootKey, "renderheight", &g_viewerSettings.height );
RegReadBool( hRootKey, "faceposerToolsDriveMouth", &g_viewerSettings.faceposerToolsDriveMouth );
return true;
}
bool SaveViewerSettings (const char *filename, StudioModel *pModel )
{
LONG lResult; // Registry function result code
DWORD dwDisposition; // Type of key opening event
if (filename == NULL || pModel == NULL)
return false;
HKEY hModelKey;
lResult = RegViewerSettingsKey( filename, &hModelKey, &dwDisposition);
if (lResult != ERROR_SUCCESS) // Failure
return false;
MDLCACHE_CRITICAL_SECTION_( g_pMDLCache );
CStudioHdr *hdr = pModel->GetStudioHdr();
if ( !hdr )
return false;
RegWriteQAngle( hModelKey, "Rot", pModel->m_angles );
RegWriteVector( hModelKey, "Trans", pModel->m_origin );
RegWriteColor( hModelKey, "bgColor", g_viewerSettings.bgColor );
RegWriteColor( hModelKey, "gColor", g_viewerSettings.gColor );
RegWriteColor( hModelKey, "lColor", g_viewerSettings.lColor );
RegWriteColor( hModelKey, "aColor", g_viewerSettings.aColor );
RegWriteQAngle( hModelKey, "lightrot", g_viewerSettings.lightrot );
RegWriteString( hModelKey, "sequence", hdr->pSeqdesc( pModel->GetSequence() ).pszLabel() );
RegWriteString( hModelKey, "overlaySequence0", hdr->pSeqdesc( pModel->GetOverlaySequence( 0 ) ).pszLabel() );
RegWriteFloat( hModelKey, "overlayWeight0", pModel->GetOverlaySequenceWeight( 0 ) );
RegWriteString( hModelKey, "overlaySequence1", hdr->pSeqdesc( pModel->GetOverlaySequence( 1 ) ).pszLabel() );
RegWriteFloat( hModelKey, "overlayWeight1", pModel->GetOverlaySequenceWeight( 1 ) );
RegWriteString( hModelKey, "overlaySequence2", hdr->pSeqdesc( pModel->GetOverlaySequence( 2 ) ).pszLabel() );
RegWriteFloat( hModelKey, "overlayWeight2", pModel->GetOverlaySequenceWeight( 2 ) );
RegWriteString( hModelKey, "overlaySequence3", hdr->pSeqdesc( pModel->GetOverlaySequence( 3 ) ).pszLabel() );
RegWriteFloat( hModelKey, "overlayWeight3", pModel->GetOverlaySequenceWeight( 3 ) );
RegWriteFloat( hModelKey, "speedscale", g_viewerSettings.speedScale );
RegWriteInt( hModelKey, "viewermode", g_viewerSettings.application_mode );
RegWriteInt( hModelKey, "thumbnailsize", g_viewerSettings.thumbnailsize );
RegWriteInt( hModelKey, "thumbnailsizeanim", g_viewerSettings.thumbnailsizeanim );
RegWriteInt( hModelKey, "speechapiindex", g_viewerSettings.speechapiindex );
RegWriteInt( hModelKey, "cclanguageid", g_viewerSettings.cclanguageid );
RegWriteInt( hModelKey, "showground", g_viewerSettings.showGround );
RegWriteInt( hModelKey, "showbackground", g_viewerSettings.showBackground );
RegWriteInt( hModelKey, "showshadow", g_viewerSettings.showShadow );
RegWriteInt( hModelKey, "showillumpos", g_viewerSettings.showIllumPosition );
RegWriteInt( hModelKey, "enablenormalmapping", g_viewerSettings.enableNormalMapping );
RegWriteInt( hModelKey, "playsounds", g_viewerSettings.playSounds );
RegWriteInt( hModelKey, "showoriginaxis", g_viewerSettings.showOriginAxis );
RegWriteFloat( hModelKey, "originaxislength", g_viewerSettings.originAxisLength );
char merge_buffer[32];
for ( int i = 0; i < HLMV_MAX_MERGED_MODELS; i++ )
{
Q_snprintf( merge_buffer, sizeof( merge_buffer ), "merge%d", i + 1 );
RegWriteString( hModelKey, merge_buffer, g_viewerSettings.mergeModelFile[i] );
}
return true;
}
bool SaveViewerRootSettings( void )
{
LONG lResult; // Registry function result code
DWORD dwDisposition; // Type of key opening event
HKEY hRootKey;
lResult = RegViewerRootKey( &hRootKey, &dwDisposition);
if (lResult != ERROR_SUCCESS) // Failure
return false;
RegWriteInt( hRootKey, "renderxpos", g_viewerSettings.xpos );
RegWriteInt( hRootKey, "renderypos", g_viewerSettings.ypos );
RegWriteInt( hRootKey, "renderwidth", g_viewerSettings.width );
RegWriteInt( hRootKey, "renderheight", g_viewerSettings.height );
RegWriteInt( hRootKey, "faceposerToolsDriveMouth", g_viewerSettings.faceposerToolsDriveMouth ? 1 : 0 );
return true;
}

157
utils/hlmv/viewersettings.h Normal file
View File

@@ -0,0 +1,157 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
//
// Half-Life Model Viewer (c) 1999 by Mete Ciragan
//
// file: ViewerSettings.h
// last modified: May 29 1999, Mete Ciragan
// copyright: The programs and associated files contained in this
// distribution were developed by Mete Ciragan. The programs
// are not in the public domain, but they are freely
// distributable without licensing fees. These programs are
// provided without guarantee or warrantee expressed or
// implied.
//
// version: 1.2
//
// email: mete@swissquake.ch
// web: http://www.swissquake.ch/chumbalum-soft/
//
#ifndef INCLUDED_VIEWERSETTINGS
#define INCLUDED_VIEWERSETTINGS
#include "mathlib/vector.h"
enum // render modes
{
RM_WIREFRAME = 0,
// RM_FLATSHADED,
RM_SMOOTHSHADED,
RM_TEXTURED,
RM_BONEWEIGHTS,
RM_SHOWBADVERTEXDATA,
RM_TEXCOORDS,
};
#define HLMV_MAX_MERGED_MODELS 12
struct ViewerSettings
{
char registrysubkey[ 64 ];
int application_mode; // 0 expression, 1 choreo
bool showHitBoxes;
bool showBones;
bool showAttachments;
bool showPhysicsModel;
bool showPhysicsPreview;
bool showSequenceBoxes;
bool enableIK;
bool enableTargetIK;
bool showNormals;
bool showTangentFrame;
bool overlayWireframe;
bool enableNormalMapping;
bool enableParallaxMapping;
bool enableSpecular;
bool showIllumPosition;
bool playSounds;
// Current attachment we're editing. -1 if none.
int m_iEditAttachment;
bool showLightingCenter;
int highlightPhysicsBone;
int highlightHitbox;
int highlightBone;
QAngle lightrot; // light rotation
float lColor[4]; // directional color
float aColor[4]; // ambient color
// external
// model
float fov; // horizontal field of view
// render
int renderMode;
bool showBackground;
bool showGround;
bool showTexture;
bool showMovement;
bool showShadow;
int texture;
int skin;
int materialIndex;
bool showOriginAxis;
float originAxisLength;
// animation
float speedScale;
bool blendSequenceChanges;
bool animateWeapons;
// bodyparts and bonecontrollers
//int submodels[32];
//float controllers[8];
// fullscreen
int xpos, ypos;
int width, height;
bool cds;
// colors
float bgColor[4]; // background color
float gColor[4];
// misc
bool pause;
bool rotating;
bool mousedown;
// only used for fullscreen mode
// char modelFile[256];
//char backgroundTexFile[256];
//char groundTexFile[256];
int lod;
bool autoLOD;
bool softwareSkin;
bool overbright;
int thumbnailsize;
int thumbnailsizeanim;
int speechapiindex;
int cclanguageid; // Close captioning language id (see sentence.h enum)
bool showHidden;
bool showActivities;
bool faceposerToolsDriveMouth;
char mergeModelFile[HLMV_MAX_MERGED_MODELS][256];
ViewerSettings();
};
extern ViewerSettings g_viewerSettings;
class StudioModel;
void InitViewerSettings ( const char *subkey );
bool LoadViewerSettings (const char *filename, StudioModel *pModel );
bool SaveViewerSettings (const char *filename, StudioModel *pModel );
bool LoadViewerRootSettings( void );
bool SaveViewerRootSettings( void );
// For saving/loading "global" settings
bool LoadViewerSettingsInt( char const *keyname, int *value );
bool SaveViewerSettingsInt ( const char *keyname, int value );
#endif // INCLUDED_VIEWERSETTINGS