Moved modified HL SDK to trunk
This commit is contained in:
268
hlsdk/utils/mdlviewer/mdlviewer.cpp
Normal file
268
hlsdk/utils/mdlviewer/mdlviewer.cpp
Normal file
@ -0,0 +1,268 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
****/
|
||||
// updates:
|
||||
// 1-4-98 fixed initialization
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <gl\GL.h>
|
||||
#include <gl\GLU.h>
|
||||
#include <gl\glut.h>
|
||||
|
||||
#include "mathlib.h"
|
||||
#include "..\..\engine\studio.h"
|
||||
#include "mdlviewer.h"
|
||||
|
||||
|
||||
#pragma warning( disable : 4244 ) // conversion from 'double ' to 'float ', possible loss of data
|
||||
#pragma warning( disable : 4305 ) // truncation from 'const double ' to 'float '
|
||||
|
||||
vec3_t g_vright; // needs to be set to viewer's right in order for chrome to work
|
||||
float g_lambert = 1.5;
|
||||
|
||||
float gldepthmin = 0;
|
||||
float gldepthmax = 10.0;
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_Clear
|
||||
=============
|
||||
*/
|
||||
void R_Clear (void)
|
||||
{
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
glDepthRange (gldepthmin, gldepthmax);
|
||||
glDepthMask( 1 );
|
||||
}
|
||||
|
||||
static StudioModel tempmodel;
|
||||
|
||||
void mdlviewer_display( )
|
||||
{
|
||||
R_Clear( );
|
||||
|
||||
tempmodel.SetBlending( 0, 0.0 );
|
||||
tempmodel.SetBlending( 1, 0.0 );
|
||||
|
||||
static float prev;
|
||||
float curr = GetTickCount( ) / 1000.0;
|
||||
tempmodel.AdvanceFrame( curr - prev );
|
||||
prev = curr;
|
||||
|
||||
tempmodel.DrawModel( );
|
||||
}
|
||||
|
||||
|
||||
void mdlviewer_init( char *modelname )
|
||||
{
|
||||
// make a bogus texture
|
||||
// R_InitTexture( );
|
||||
|
||||
tempmodel.Init( modelname );
|
||||
tempmodel.SetSequence( 0 );
|
||||
|
||||
tempmodel.SetController( 0, 0.0 );
|
||||
tempmodel.SetController( 1, 0.0 );
|
||||
tempmodel.SetController( 2, 0.0 );
|
||||
tempmodel.SetController( 3, 0.0 );
|
||||
tempmodel.SetMouth( 0 );
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(50.,1.,.1,10.);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glClearColor( 0, 0, 0.5, 0 );
|
||||
}
|
||||
|
||||
|
||||
void mdlviewer_nextsequence( void )
|
||||
{
|
||||
int iSeq = tempmodel.GetSequence( );
|
||||
if (iSeq == tempmodel.SetSequence( iSeq + 1 ))
|
||||
{
|
||||
tempmodel.SetSequence( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
static int pstyle;
|
||||
static int translate = 1;
|
||||
static int mesh = 1;
|
||||
static float transx = 0, transy = 0, transz = -2, rotx=235, roty=-90;
|
||||
static float amplitude = 0.03;
|
||||
static float freq = 5.0f;
|
||||
static float phase = .00003;
|
||||
static int ox = -1, oy = -1;
|
||||
static int show_t = 1;
|
||||
static int mot;
|
||||
#define PAN 1
|
||||
#define ROT 2
|
||||
#define ZOOM 3
|
||||
|
||||
void pan(int x, int y)
|
||||
{
|
||||
transx += (x-ox)/500.;
|
||||
transy -= (y-oy)/500.;
|
||||
ox = x; oy = y;
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void zoom(int x, int y)
|
||||
{
|
||||
transz += (x-ox)/20.;
|
||||
ox = x;
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void rotate(int x, int y)
|
||||
{
|
||||
rotx += x-ox;
|
||||
if (rotx > 360.) rotx -= 360.;
|
||||
else if (rotx < -360.) rotx += 360.;
|
||||
roty += y-oy;
|
||||
if (roty > 360.) roty -= 360.;
|
||||
else if (roty < -360.) roty += 360.;
|
||||
ox = x; oy = y;
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void motion(int x, int y)
|
||||
{
|
||||
if (mot == PAN)
|
||||
pan(x, y);
|
||||
else if (mot == ROT)
|
||||
rotate(x,y);
|
||||
else if ( mot == ZOOM )
|
||||
zoom( x, y );
|
||||
}
|
||||
|
||||
void mouse(int button, int state, int x, int y)
|
||||
{
|
||||
if(state == GLUT_DOWN) {
|
||||
switch(button) {
|
||||
case GLUT_LEFT_BUTTON:
|
||||
mot = PAN;
|
||||
motion(ox = x, oy = y);
|
||||
break;
|
||||
case GLUT_RIGHT_BUTTON:
|
||||
mot = ROT;
|
||||
motion(ox = x, oy = y);
|
||||
break;
|
||||
case GLUT_MIDDLE_BUTTON:
|
||||
break;
|
||||
}
|
||||
} else if (state == GLUT_UP) {
|
||||
mot = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void help(void)
|
||||
{
|
||||
printf("left mouse - pan\n");
|
||||
printf("right mouse - rotate\n");
|
||||
}
|
||||
|
||||
void init( char *arg )
|
||||
{
|
||||
mdlviewer_init( arg );
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(50.,1.,.1,10.);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
// glTranslatef(0.,0.,-5.5);
|
||||
// glTranslatef(-.2.,1.0,-1.5);
|
||||
|
||||
glClearColor( 0, 0, 0.5, 0 );
|
||||
}
|
||||
|
||||
void display(void)
|
||||
{
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
glTranslatef(transx, transy, transz);
|
||||
|
||||
glRotatef(rotx, 0., 1., 0.);
|
||||
glRotatef(roty, 1., 0., 0.);
|
||||
|
||||
glScalef( 0.01, 0.01, 0.01 );
|
||||
glCullFace( GL_FRONT );
|
||||
glEnable( GL_DEPTH_TEST );
|
||||
|
||||
mdlviewer_display( );
|
||||
|
||||
glPopMatrix();
|
||||
glutSwapBuffers();
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void reshape(int w, int h)
|
||||
{
|
||||
glViewport(0, 0, w, h);
|
||||
}
|
||||
|
||||
/*ARGSUSED1*/
|
||||
void key(unsigned char key, int x, int y)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
case 'h':
|
||||
help();
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
printf("Translation: %f, %f %f\n", transx, transy, transz );
|
||||
break;
|
||||
|
||||
case '\033': // Escape
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
mdlviewer_nextsequence( );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("usage : %s <filename>\n", argv[0] );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
glutInitWindowSize(512, 512);
|
||||
glutInit(&argc, argv);
|
||||
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
|
||||
(void)glutCreateWindow(argv[0]);
|
||||
init( argv[1] );
|
||||
glutDisplayFunc(display);
|
||||
glutKeyboardFunc(key);
|
||||
glutReshapeFunc(reshape);
|
||||
glutMouseFunc(mouse);
|
||||
glutMotionFunc(motion);
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
||||
|
78
hlsdk/utils/mdlviewer/mdlviewer.h
Normal file
78
hlsdk/utils/mdlviewer/mdlviewer.h
Normal file
@ -0,0 +1,78 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, 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.
|
||||
*
|
||||
****/
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
class StudioModel
|
||||
{
|
||||
public:
|
||||
void Init( char *modelname );
|
||||
void DrawModel( void );
|
||||
void AdvanceFrame( float dt );
|
||||
|
||||
void ExtractBbox( float *mins, float *maxs );
|
||||
|
||||
int SetSequence( int iSequence );
|
||||
int GetSequence( void );
|
||||
void GetSequenceInfo( float *pflFrameRate, float *pflGroundSpeed );
|
||||
|
||||
float SetController( int iController, float flValue );
|
||||
float SetMouth( float flValue );
|
||||
float SetBlending( int iBlender, float flValue );
|
||||
int SetBodygroup( int iGroup, int iValue );
|
||||
int SetSkin( int iValue );
|
||||
|
||||
private:
|
||||
// entity settings
|
||||
vec3_t m_origin;
|
||||
vec3_t m_angles;
|
||||
int m_sequence; // sequence index
|
||||
float m_frame; // frame
|
||||
int m_bodynum; // bodypart selection
|
||||
int m_skinnum; // skin group selection
|
||||
byte m_controller[4]; // bone controllers
|
||||
byte m_blending[2]; // animation blending
|
||||
byte m_mouth; // mouth position
|
||||
|
||||
// internal data
|
||||
studiohdr_t *m_pstudiohdr;
|
||||
mstudiomodel_t *m_pmodel;
|
||||
|
||||
studiohdr_t *m_ptexturehdr;
|
||||
studioseqhdr_t *m_panimhdr[32];
|
||||
|
||||
vec4_t m_adj; // FIX: non persistant, make static
|
||||
|
||||
studiohdr_t *LoadModel( char *modelname );
|
||||
studioseqhdr_t *LoadDemandSequences( char *modelname );
|
||||
|
||||
void CalcBoneAdj( void );
|
||||
void CalcBoneQuaternion( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *q );
|
||||
void CalcBonePosition( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *pos );
|
||||
void CalcRotations ( vec3_t *pos, vec4_t *q, mstudioseqdesc_t *pseqdesc, mstudioanim_t *panim, float f );
|
||||
mstudioanim_t *GetAnim( mstudioseqdesc_t *pseqdesc );
|
||||
void SlerpBones( vec4_t q1[], vec3_t pos1[], vec4_t q2[], vec3_t pos2[], float s );
|
||||
void SetUpBones ( void );
|
||||
|
||||
void DrawPoints( void );
|
||||
|
||||
void Lighting (float *lv, int bone, int flags, vec3_t normal);
|
||||
void Chrome (int *chrome, int bone, vec3_t normal);
|
||||
|
||||
void SetupLighting( void );
|
||||
|
||||
void SetupModel ( int bodypart );
|
||||
|
||||
void UploadTexture( mstudiotexture_t *ptexture, byte *data, byte *pal );
|
||||
};
|
||||
|
||||
extern vec3_t g_vright; // needs to be set to viewer's right in order for chrome to work
|
||||
extern float g_lambert; // modifier for pseudo-hemispherical lighting
|
||||
|
122
hlsdk/utils/mdlviewer/msvc6/mdlviewer.dsp
Normal file
122
hlsdk/utils/mdlviewer/msvc6/mdlviewer.dsp
Normal file
@ -0,0 +1,122 @@
|
||||
# Microsoft Developer Studio Project File - Name="mdlviewer" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=mdlviewer - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "mdlviewer.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "mdlviewer.mak" CFG="mdlviewer - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "mdlviewer - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "mdlviewer - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""$/SDKSrc/Tools/utils/mdlviewer", AIHBAAAA"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "mdlviewer - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\common" /I "..\..\..\common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib glut32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "mdlviewer - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "mdlviewer___Win32_Debug"
|
||||
# PROP BASE Intermediate_Dir "mdlviewer___Win32_Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\common" /I "..\..\..\common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glut32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "mdlviewer - Win32 Release"
|
||||
# Name "mdlviewer - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\common\mathlib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\mdlviewer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\studio_render.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\studio_utils.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\common\mathlib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\mdlviewer.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
29
hlsdk/utils/mdlviewer/msvc6/mdlviewer.dsw
Normal file
29
hlsdk/utils/mdlviewer/msvc6/mdlviewer.dsw
Normal file
@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "mdlviewer"=".\mdlviewer.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
246
hlsdk/utils/mdlviewer/msvc7/mdlviewer.vcproj
Normal file
246
hlsdk/utils/mdlviewer/msvc7/mdlviewer.vcproj
Normal file
@ -0,0 +1,246 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="mdlviewer"
|
||||
ProjectGUID="{C4694871-3C3D-4D8D-AC8C-A55C6A80800E}"
|
||||
SccProjectName=""$/SDKSrc/Tools/utils/mdlviewer", AIHBAAAA"
|
||||
SccLocalPath=".">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\common,..\..\..\common"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile=".\Debug/mdlviewer.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
BrowseInformation="1"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="glu32.lib odbc32.lib odbccp32.lib opengl32.lib glut32.lib"
|
||||
OutputFile=".\Debug/mdlviewer.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\Debug/mdlviewer.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\Debug/mdlviewer.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="..\..\common,..\..\..\common"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile=".\Release/mdlviewer.pch"
|
||||
AssemblerListingLocation=".\Release/"
|
||||
ObjectFile=".\Release/"
|
||||
ProgramDataBaseFileName=".\Release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib glu32.lib glut32.lib"
|
||||
OutputFile=".\Release/mdlviewer.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
ProgramDatabaseFile=".\Release/mdlviewer.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\Release/mdlviewer.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
|
||||
<File
|
||||
RelativePath="..\..\common\mathlib.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
BasicRuntimeChecks="3"
|
||||
BrowseInformation="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\mdlviewer.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
BasicRuntimeChecks="3"
|
||||
BrowseInformation="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\studio_render.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
BasicRuntimeChecks="3"
|
||||
BrowseInformation="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\studio_utils.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
BasicRuntimeChecks="3"
|
||||
BrowseInformation="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl">
|
||||
<File
|
||||
RelativePath="..\..\common\mathlib.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\mdlviewer.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
334
hlsdk/utils/mdlviewer/msvc8/mdlviewer.vcproj
Normal file
334
hlsdk/utils/mdlviewer/msvc8/mdlviewer.vcproj
Normal file
@ -0,0 +1,334 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="mdlviewer"
|
||||
ProjectGUID="{C4694871-3C3D-4D8D-AC8C-A55C6A80800E}"
|
||||
RootNamespace="mdlviewer"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\Debug/mdlviewer.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\common,..\..\..\common"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile=".\Debug/mdlviewer.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
BrowseInformation="1"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="glu32.lib odbc32.lib odbccp32.lib opengl32.lib glut32.lib"
|
||||
OutputFile=".\Debug/mdlviewer.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile=".\Debug/mdlviewer.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\Release/mdlviewer.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="..\..\common,..\..\..\common"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile=".\Release/mdlviewer.pch"
|
||||
AssemblerListingLocation=".\Release/"
|
||||
ObjectFile=".\Release/"
|
||||
ProgramDataBaseFileName=".\Release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
CompileAs="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib glu32.lib glut32.lib"
|
||||
OutputFile=".\Release/mdlviewer.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile=".\Release/mdlviewer.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\common\mathlib.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
BasicRuntimeChecks="3"
|
||||
BrowseInformation="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\mdlviewer.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
BasicRuntimeChecks="3"
|
||||
BrowseInformation="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\studio_render.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
BasicRuntimeChecks="3"
|
||||
BrowseInformation="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\studio_utils.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
BasicRuntimeChecks="3"
|
||||
BrowseInformation="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\common\mathlib.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\mdlviewer.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
727
hlsdk/utils/mdlviewer/studio_render.cpp
Normal file
727
hlsdk/utils/mdlviewer/studio_render.cpp
Normal file
@ -0,0 +1,727 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, 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.
|
||||
*
|
||||
****/
|
||||
// studio_render.cpp: routines for drawing Half-Life 3DStudio models
|
||||
// updates:
|
||||
// 1-4-99 fixed AdvanceFrame wraping bug
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <gl\gl.h>
|
||||
#include <gl\glu.h>
|
||||
|
||||
#pragma warning( disable : 4244 ) // double to float
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "mathlib.h"
|
||||
#include "..\..\engine\studio.h"
|
||||
#include "mdlviewer.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
vec3_t g_xformverts[MAXSTUDIOVERTS]; // transformed vertices
|
||||
vec3_t g_lightvalues[MAXSTUDIOVERTS]; // light surface normals
|
||||
vec3_t *g_pxformverts;
|
||||
vec3_t *g_pvlightvalues;
|
||||
|
||||
vec3_t g_lightvec; // light vector in model reference frame
|
||||
vec3_t g_blightvec[MAXSTUDIOBONES]; // light vectors in bone reference frames
|
||||
int g_ambientlight; // ambient world light
|
||||
float g_shadelight; // direct world light
|
||||
vec3_t g_lightcolor;
|
||||
|
||||
int g_smodels_total; // cookie
|
||||
|
||||
float g_bonetransform[MAXSTUDIOBONES][3][4]; // bone transformation matrix
|
||||
|
||||
int g_chrome[MAXSTUDIOVERTS][2]; // texture coords for surface normals
|
||||
int g_chromeage[MAXSTUDIOBONES]; // last time chrome vectors were updated
|
||||
vec3_t g_chromeup[MAXSTUDIOBONES]; // chrome vector "up" in bone reference frames
|
||||
vec3_t g_chromeright[MAXSTUDIOBONES]; // chrome vector "right" in bone reference frames
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void StudioModel::CalcBoneAdj( )
|
||||
{
|
||||
int i, j;
|
||||
float value;
|
||||
mstudiobonecontroller_t *pbonecontroller;
|
||||
|
||||
pbonecontroller = (mstudiobonecontroller_t *)((byte *)m_pstudiohdr + m_pstudiohdr->bonecontrollerindex);
|
||||
|
||||
for (j = 0; j < m_pstudiohdr->numbonecontrollers; j++)
|
||||
{
|
||||
i = pbonecontroller[j].index;
|
||||
if (i <= 3)
|
||||
{
|
||||
// check for 360% wrapping
|
||||
if (pbonecontroller[j].type & STUDIO_RLOOP)
|
||||
{
|
||||
value = m_controller[i] * (360.0/256.0) + pbonecontroller[j].start;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = m_controller[i] / 255.0;
|
||||
if (value < 0) value = 0;
|
||||
if (value > 1.0) value = 1.0;
|
||||
value = (1.0 - value) * pbonecontroller[j].start + value * pbonecontroller[j].end;
|
||||
}
|
||||
// Con_DPrintf( "%d %d %f : %f\n", m_controller[j], m_prevcontroller[j], value, dadt );
|
||||
}
|
||||
else
|
||||
{
|
||||
value = m_mouth / 64.0;
|
||||
if (value > 1.0) value = 1.0;
|
||||
value = (1.0 - value) * pbonecontroller[j].start + value * pbonecontroller[j].end;
|
||||
// Con_DPrintf("%d %f\n", mouthopen, value );
|
||||
}
|
||||
switch(pbonecontroller[j].type & STUDIO_TYPES)
|
||||
{
|
||||
case STUDIO_XR:
|
||||
case STUDIO_YR:
|
||||
case STUDIO_ZR:
|
||||
m_adj[j] = value * (Q_PI / 180.0);
|
||||
break;
|
||||
case STUDIO_X:
|
||||
case STUDIO_Y:
|
||||
case STUDIO_Z:
|
||||
m_adj[j] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StudioModel::CalcBoneQuaternion( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *q )
|
||||
{
|
||||
int j, k;
|
||||
vec4_t q1, q2;
|
||||
vec3_t angle1, angle2;
|
||||
mstudioanimvalue_t *panimvalue;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
if (panim->offset[j+3] == 0)
|
||||
{
|
||||
angle2[j] = angle1[j] = pbone->value[j+3]; // default;
|
||||
}
|
||||
else
|
||||
{
|
||||
panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j+3]);
|
||||
k = frame;
|
||||
while (panimvalue->num.total <= k)
|
||||
{
|
||||
k -= panimvalue->num.total;
|
||||
panimvalue += panimvalue->num.valid + 1;
|
||||
}
|
||||
// Bah, missing blend!
|
||||
if (panimvalue->num.valid > k)
|
||||
{
|
||||
angle1[j] = panimvalue[k+1].value;
|
||||
|
||||
if (panimvalue->num.valid > k + 1)
|
||||
{
|
||||
angle2[j] = panimvalue[k+2].value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (panimvalue->num.total > k + 1)
|
||||
angle2[j] = angle1[j];
|
||||
else
|
||||
angle2[j] = panimvalue[panimvalue->num.valid+2].value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
angle1[j] = panimvalue[panimvalue->num.valid].value;
|
||||
if (panimvalue->num.total > k + 1)
|
||||
{
|
||||
angle2[j] = angle1[j];
|
||||
}
|
||||
else
|
||||
{
|
||||
angle2[j] = panimvalue[panimvalue->num.valid + 2].value;
|
||||
}
|
||||
}
|
||||
angle1[j] = pbone->value[j+3] + angle1[j] * pbone->scale[j+3];
|
||||
angle2[j] = pbone->value[j+3] + angle2[j] * pbone->scale[j+3];
|
||||
}
|
||||
|
||||
if (pbone->bonecontroller[j+3] != -1)
|
||||
{
|
||||
angle1[j] += m_adj[pbone->bonecontroller[j+3]];
|
||||
angle2[j] += m_adj[pbone->bonecontroller[j+3]];
|
||||
}
|
||||
}
|
||||
|
||||
if (!VectorCompare( angle1, angle2 ))
|
||||
{
|
||||
AngleQuaternion( angle1, q1 );
|
||||
AngleQuaternion( angle2, q2 );
|
||||
QuaternionSlerp( q1, q2, s, q );
|
||||
}
|
||||
else
|
||||
{
|
||||
AngleQuaternion( angle1, q );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StudioModel::CalcBonePosition( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *pos )
|
||||
{
|
||||
int j, k;
|
||||
mstudioanimvalue_t *panimvalue;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
pos[j] = pbone->value[j]; // default;
|
||||
if (panim->offset[j] != 0)
|
||||
{
|
||||
panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j]);
|
||||
|
||||
k = frame;
|
||||
// find span of values that includes the frame we want
|
||||
while (panimvalue->num.total <= k)
|
||||
{
|
||||
k -= panimvalue->num.total;
|
||||
panimvalue += panimvalue->num.valid + 1;
|
||||
}
|
||||
// if we're inside the span
|
||||
if (panimvalue->num.valid > k)
|
||||
{
|
||||
// and there's more data in the span
|
||||
if (panimvalue->num.valid > k + 1)
|
||||
{
|
||||
pos[j] += (panimvalue[k+1].value * (1.0 - s) + s * panimvalue[k+2].value) * pbone->scale[j];
|
||||
}
|
||||
else
|
||||
{
|
||||
pos[j] += panimvalue[k+1].value * pbone->scale[j];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// are we at the end of the repeating values section and there's another section with data?
|
||||
if (panimvalue->num.total <= k + 1)
|
||||
{
|
||||
pos[j] += (panimvalue[panimvalue->num.valid].value * (1.0 - s) + s * panimvalue[panimvalue->num.valid + 2].value) * pbone->scale[j];
|
||||
}
|
||||
else
|
||||
{
|
||||
pos[j] += panimvalue[panimvalue->num.valid].value * pbone->scale[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pbone->bonecontroller[j] != -1)
|
||||
{
|
||||
pos[j] += m_adj[pbone->bonecontroller[j]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StudioModel::CalcRotations ( vec3_t *pos, vec4_t *q, mstudioseqdesc_t *pseqdesc, mstudioanim_t *panim, float f )
|
||||
{
|
||||
int i;
|
||||
int frame;
|
||||
mstudiobone_t *pbone;
|
||||
float s;
|
||||
|
||||
frame = (int)f;
|
||||
s = (f - frame);
|
||||
|
||||
// add in programatic controllers
|
||||
CalcBoneAdj( );
|
||||
|
||||
pbone = (mstudiobone_t *)((byte *)m_pstudiohdr + m_pstudiohdr->boneindex);
|
||||
for (i = 0; i < m_pstudiohdr->numbones; i++, pbone++, panim++)
|
||||
{
|
||||
CalcBoneQuaternion( frame, s, pbone, panim, q[i] );
|
||||
CalcBonePosition( frame, s, pbone, panim, pos[i] );
|
||||
}
|
||||
|
||||
if (pseqdesc->motiontype & STUDIO_X)
|
||||
pos[pseqdesc->motionbone][0] = 0.0;
|
||||
if (pseqdesc->motiontype & STUDIO_Y)
|
||||
pos[pseqdesc->motionbone][1] = 0.0;
|
||||
if (pseqdesc->motiontype & STUDIO_Z)
|
||||
pos[pseqdesc->motionbone][2] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
mstudioanim_t * StudioModel::GetAnim( mstudioseqdesc_t *pseqdesc )
|
||||
{
|
||||
mstudioseqgroup_t *pseqgroup;
|
||||
pseqgroup = (mstudioseqgroup_t *)((byte *)m_pstudiohdr + m_pstudiohdr->seqgroupindex) + pseqdesc->seqgroup;
|
||||
|
||||
if (pseqdesc->seqgroup == 0)
|
||||
{
|
||||
return (mstudioanim_t *)((byte *)m_pstudiohdr + pseqgroup->data + pseqdesc->animindex);
|
||||
}
|
||||
|
||||
return (mstudioanim_t *)((byte *)m_panimhdr[pseqdesc->seqgroup] + pseqdesc->animindex);
|
||||
}
|
||||
|
||||
|
||||
void StudioModel::SlerpBones( vec4_t q1[], vec3_t pos1[], vec4_t q2[], vec3_t pos2[], float s )
|
||||
{
|
||||
int i;
|
||||
vec4_t q3;
|
||||
float s1;
|
||||
|
||||
if (s < 0) s = 0;
|
||||
else if (s > 1.0) s = 1.0;
|
||||
|
||||
s1 = 1.0 - s;
|
||||
|
||||
for (i = 0; i < m_pstudiohdr->numbones; i++)
|
||||
{
|
||||
QuaternionSlerp( q1[i], q2[i], s, q3 );
|
||||
q1[i][0] = q3[0];
|
||||
q1[i][1] = q3[1];
|
||||
q1[i][2] = q3[2];
|
||||
q1[i][3] = q3[3];
|
||||
pos1[i][0] = pos1[i][0] * s1 + pos2[i][0] * s;
|
||||
pos1[i][1] = pos1[i][1] * s1 + pos2[i][1] * s;
|
||||
pos1[i][2] = pos1[i][2] * s1 + pos2[i][2] * s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StudioModel::AdvanceFrame( float dt )
|
||||
{
|
||||
mstudioseqdesc_t *pseqdesc;
|
||||
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pstudiohdr + m_pstudiohdr->seqindex) + m_sequence;
|
||||
|
||||
if (dt > 0.1)
|
||||
dt = (float)0.1;
|
||||
m_frame += dt * pseqdesc->fps;
|
||||
|
||||
if (pseqdesc->numframes <= 1)
|
||||
{
|
||||
m_frame = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// wrap
|
||||
m_frame -= (int)(m_frame / (pseqdesc->numframes - 1)) * (pseqdesc->numframes - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StudioModel::SetUpBones ( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
mstudiobone_t *pbones;
|
||||
mstudioseqdesc_t *pseqdesc;
|
||||
mstudioanim_t *panim;
|
||||
|
||||
static vec3_t pos[MAXSTUDIOBONES];
|
||||
float bonematrix[3][4];
|
||||
static vec4_t q[MAXSTUDIOBONES];
|
||||
|
||||
static vec3_t pos2[MAXSTUDIOBONES];
|
||||
static vec4_t q2[MAXSTUDIOBONES];
|
||||
static vec3_t pos3[MAXSTUDIOBONES];
|
||||
static vec4_t q3[MAXSTUDIOBONES];
|
||||
static vec3_t pos4[MAXSTUDIOBONES];
|
||||
static vec4_t q4[MAXSTUDIOBONES];
|
||||
|
||||
|
||||
if (m_sequence >= m_pstudiohdr->numseq) {
|
||||
m_sequence = 0;
|
||||
}
|
||||
|
||||
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pstudiohdr + m_pstudiohdr->seqindex) + m_sequence;
|
||||
|
||||
panim = GetAnim( pseqdesc );
|
||||
CalcRotations( pos, q, pseqdesc, panim, m_frame );
|
||||
|
||||
if (pseqdesc->numblends > 1)
|
||||
{
|
||||
float s;
|
||||
|
||||
panim += m_pstudiohdr->numbones;
|
||||
CalcRotations( pos2, q2, pseqdesc, panim, m_frame );
|
||||
s = m_blending[0] / 255.0;
|
||||
|
||||
SlerpBones( q, pos, q2, pos2, s );
|
||||
|
||||
if (pseqdesc->numblends == 4)
|
||||
{
|
||||
panim += m_pstudiohdr->numbones;
|
||||
CalcRotations( pos3, q3, pseqdesc, panim, m_frame );
|
||||
|
||||
panim += m_pstudiohdr->numbones;
|
||||
CalcRotations( pos4, q4, pseqdesc, panim, m_frame );
|
||||
|
||||
s = m_blending[0] / 255.0;
|
||||
SlerpBones( q3, pos3, q4, pos4, s );
|
||||
|
||||
s = m_blending[1] / 255.0;
|
||||
SlerpBones( q, pos, q3, pos3, s );
|
||||
}
|
||||
}
|
||||
|
||||
pbones = (mstudiobone_t *)((byte *)m_pstudiohdr + m_pstudiohdr->boneindex);
|
||||
|
||||
for (i = 0; i < m_pstudiohdr->numbones; i++) {
|
||||
QuaternionMatrix( q[i], bonematrix );
|
||||
|
||||
bonematrix[0][3] = pos[i][0];
|
||||
bonematrix[1][3] = pos[i][1];
|
||||
bonematrix[2][3] = pos[i][2];
|
||||
|
||||
if (pbones[i].parent == -1) {
|
||||
memcpy(g_bonetransform[i], bonematrix, sizeof(float) * 12);
|
||||
}
|
||||
else {
|
||||
R_ConcatTransforms (g_bonetransform[pbones[i].parent], bonematrix, g_bonetransform[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
StudioModel::TransformFinalVert
|
||||
================
|
||||
*/
|
||||
void StudioModel::Lighting (float *lv, int bone, int flags, vec3_t normal)
|
||||
{
|
||||
float illum;
|
||||
float lightcos;
|
||||
|
||||
illum = g_ambientlight;
|
||||
|
||||
if (flags & STUDIO_NF_FLATSHADE)
|
||||
{
|
||||
illum += g_shadelight * 0.8;
|
||||
}
|
||||
else
|
||||
{
|
||||
float r;
|
||||
lightcos = DotProduct (normal, g_blightvec[bone]); // -1 colinear, 1 opposite
|
||||
|
||||
if (lightcos > 1.0)
|
||||
lightcos = 1;
|
||||
|
||||
illum += g_shadelight;
|
||||
|
||||
r = g_lambert;
|
||||
if (r <= 1.0) r = 1.0;
|
||||
|
||||
lightcos = (lightcos + (r - 1.0)) / r; // do modified hemispherical lighting
|
||||
if (lightcos > 0.0)
|
||||
{
|
||||
illum -= g_shadelight * lightcos;
|
||||
}
|
||||
if (illum <= 0)
|
||||
illum = 0;
|
||||
}
|
||||
|
||||
if (illum > 255)
|
||||
illum = 255;
|
||||
*lv = illum / 255.0; // Light from 0 to 1.0
|
||||
}
|
||||
|
||||
|
||||
void StudioModel::Chrome (int *pchrome, int bone, vec3_t normal)
|
||||
{
|
||||
float n;
|
||||
|
||||
if (g_chromeage[bone] != g_smodels_total)
|
||||
{
|
||||
// calculate vectors from the viewer to the bone. This roughly adjusts for position
|
||||
vec3_t chromeupvec; // g_chrome t vector in world reference frame
|
||||
vec3_t chromerightvec; // g_chrome s vector in world reference frame
|
||||
vec3_t tmp; // vector pointing at bone in world reference frame
|
||||
VectorScale( m_origin, -1, tmp );
|
||||
tmp[0] += g_bonetransform[bone][0][3];
|
||||
tmp[1] += g_bonetransform[bone][1][3];
|
||||
tmp[2] += g_bonetransform[bone][2][3];
|
||||
VectorNormalize( tmp );
|
||||
CrossProduct( tmp, g_vright, chromeupvec );
|
||||
VectorNormalize( chromeupvec );
|
||||
CrossProduct( tmp, chromeupvec, chromerightvec );
|
||||
VectorNormalize( chromerightvec );
|
||||
|
||||
VectorIRotate( chromeupvec, g_bonetransform[bone], g_chromeup[bone] );
|
||||
VectorIRotate( chromerightvec, g_bonetransform[bone], g_chromeright[bone] );
|
||||
|
||||
g_chromeage[bone] = g_smodels_total;
|
||||
}
|
||||
|
||||
// calc s coord
|
||||
n = DotProduct( normal, g_chromeright[bone] );
|
||||
pchrome[0] = (n + 1.0) * 32; // FIX: make this a float
|
||||
|
||||
// calc t coord
|
||||
n = DotProduct( normal, g_chromeup[bone] );
|
||||
pchrome[1] = (n + 1.0) * 32; // FIX: make this a float
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
StudioModel::SetupLighting
|
||||
set some global variables based on entity position
|
||||
inputs:
|
||||
outputs:
|
||||
g_ambientlight
|
||||
g_shadelight
|
||||
================
|
||||
*/
|
||||
void StudioModel::SetupLighting ( )
|
||||
{
|
||||
int i;
|
||||
g_ambientlight = 32;
|
||||
g_shadelight = 192;
|
||||
|
||||
g_lightvec[0] = 0;
|
||||
g_lightvec[1] = 0;
|
||||
g_lightvec[2] = -1.0;
|
||||
|
||||
g_lightcolor[0] = 1.0;
|
||||
g_lightcolor[1] = 1.0;
|
||||
g_lightcolor[2] = 1.0;
|
||||
|
||||
// TODO: only do it for bones that actually have textures
|
||||
for (i = 0; i < m_pstudiohdr->numbones; i++)
|
||||
{
|
||||
VectorIRotate( g_lightvec, g_bonetransform[i], g_blightvec[i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
StudioModel::SetupModel
|
||||
based on the body part, figure out which mesh it should be using.
|
||||
inputs:
|
||||
currententity
|
||||
outputs:
|
||||
pstudiomesh
|
||||
pmdl
|
||||
=================
|
||||
*/
|
||||
|
||||
void StudioModel::SetupModel ( int bodypart )
|
||||
{
|
||||
int index;
|
||||
|
||||
if (bodypart > m_pstudiohdr->numbodyparts)
|
||||
{
|
||||
// Con_DPrintf ("StudioModel::SetupModel: no such bodypart %d\n", bodypart);
|
||||
bodypart = 0;
|
||||
}
|
||||
|
||||
mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)m_pstudiohdr + m_pstudiohdr->bodypartindex) + bodypart;
|
||||
|
||||
index = m_bodynum / pbodypart->base;
|
||||
index = index % pbodypart->nummodels;
|
||||
|
||||
m_pmodel = (mstudiomodel_t *)((byte *)m_pstudiohdr + pbodypart->modelindex) + index;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
StudioModel::DrawModel
|
||||
inputs:
|
||||
currententity
|
||||
r_entorigin
|
||||
================
|
||||
*/
|
||||
void StudioModel::DrawModel( )
|
||||
{
|
||||
int i;
|
||||
|
||||
g_smodels_total++; // render data cache cookie
|
||||
|
||||
g_pxformverts = &g_xformverts[0];
|
||||
g_pvlightvalues = &g_lightvalues[0];
|
||||
|
||||
if (m_pstudiohdr->numbodyparts == 0)
|
||||
return;
|
||||
|
||||
glPushMatrix ();
|
||||
|
||||
glTranslatef (m_origin[0], m_origin[1], m_origin[2]);
|
||||
|
||||
glRotatef (m_angles[1], 0, 0, 1);
|
||||
glRotatef (m_angles[0], 0, 1, 0);
|
||||
glRotatef (m_angles[2], 1, 0, 0);
|
||||
|
||||
// glShadeModel (GL_SMOOTH);
|
||||
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
// glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||
|
||||
SetUpBones ( );
|
||||
|
||||
SetupLighting( );
|
||||
|
||||
for (i=0 ; i < m_pstudiohdr->numbodyparts ; i++)
|
||||
{
|
||||
SetupModel( i );
|
||||
DrawPoints( );
|
||||
}
|
||||
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
|
||||
// glShadeModel (GL_FLAT);
|
||||
|
||||
// glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
|
||||
glPopMatrix ();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
|
||||
================
|
||||
*/
|
||||
void StudioModel::DrawPoints ( )
|
||||
{
|
||||
int i, j;
|
||||
mstudiomesh_t *pmesh;
|
||||
byte *pvertbone;
|
||||
byte *pnormbone;
|
||||
vec3_t *pstudioverts;
|
||||
vec3_t *pstudionorms;
|
||||
mstudiotexture_t *ptexture;
|
||||
float *av;
|
||||
float *lv;
|
||||
float lv_tmp;
|
||||
short *pskinref;
|
||||
|
||||
pvertbone = ((byte *)m_pstudiohdr + m_pmodel->vertinfoindex);
|
||||
pnormbone = ((byte *)m_pstudiohdr + m_pmodel->norminfoindex);
|
||||
ptexture = (mstudiotexture_t *)((byte *)m_ptexturehdr + m_ptexturehdr->textureindex);
|
||||
|
||||
pmesh = (mstudiomesh_t *)((byte *)m_pstudiohdr + m_pmodel->meshindex);
|
||||
|
||||
pstudioverts = (vec3_t *)((byte *)m_pstudiohdr + m_pmodel->vertindex);
|
||||
pstudionorms = (vec3_t *)((byte *)m_pstudiohdr + m_pmodel->normindex);
|
||||
|
||||
pskinref = (short *)((byte *)m_ptexturehdr + m_ptexturehdr->skinindex);
|
||||
if (m_skinnum != 0 && m_skinnum < m_ptexturehdr->numskinfamilies)
|
||||
pskinref += (m_skinnum * m_ptexturehdr->numskinref);
|
||||
|
||||
for (i = 0; i < m_pmodel->numverts; i++)
|
||||
{
|
||||
VectorTransform (pstudioverts[i], g_bonetransform[pvertbone[i]], g_pxformverts[i]);
|
||||
}
|
||||
|
||||
//
|
||||
// clip and draw all triangles
|
||||
//
|
||||
|
||||
lv = (float *)g_pvlightvalues;
|
||||
for (j = 0; j < m_pmodel->nummesh; j++)
|
||||
{
|
||||
int flags;
|
||||
flags = ptexture[pskinref[pmesh[j].skinref]].flags;
|
||||
for (i = 0; i < pmesh[j].numnorms; i++, lv += 3, pstudionorms++, pnormbone++)
|
||||
{
|
||||
Lighting (&lv_tmp, *pnormbone, flags, (float *)pstudionorms);
|
||||
|
||||
// FIX: move this check out of the inner loop
|
||||
if (flags & STUDIO_NF_CHROME)
|
||||
Chrome( g_chrome[(float (*)[3])lv - g_pvlightvalues], *pnormbone, (float *)pstudionorms );
|
||||
|
||||
lv[0] = lv_tmp * g_lightcolor[0];
|
||||
lv[1] = lv_tmp * g_lightcolor[1];
|
||||
lv[2] = lv_tmp * g_lightcolor[2];
|
||||
}
|
||||
}
|
||||
|
||||
glCullFace(GL_FRONT);
|
||||
|
||||
for (j = 0; j < m_pmodel->nummesh; j++)
|
||||
{
|
||||
float s, t;
|
||||
short *ptricmds;
|
||||
|
||||
pmesh = (mstudiomesh_t *)((byte *)m_pstudiohdr + m_pmodel->meshindex) + j;
|
||||
ptricmds = (short *)((byte *)m_pstudiohdr + pmesh->triindex);
|
||||
|
||||
s = 1.0/(float)ptexture[pskinref[pmesh->skinref]].width;
|
||||
t = 1.0/(float)ptexture[pskinref[pmesh->skinref]].height;
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, ptexture[pskinref[pmesh->skinref]].index );
|
||||
|
||||
if (ptexture[pskinref[pmesh->skinref]].flags & STUDIO_NF_CHROME)
|
||||
{
|
||||
while (i = *(ptricmds++))
|
||||
{
|
||||
if (i < 0)
|
||||
{
|
||||
glBegin( GL_TRIANGLE_FAN );
|
||||
i = -i;
|
||||
}
|
||||
else
|
||||
{
|
||||
glBegin( GL_TRIANGLE_STRIP );
|
||||
}
|
||||
|
||||
|
||||
for( ; i > 0; i--, ptricmds += 4)
|
||||
{
|
||||
// FIX: put these in as integer coords, not floats
|
||||
glTexCoord2f(g_chrome[ptricmds[1]][0]*s, g_chrome[ptricmds[1]][1]*t);
|
||||
|
||||
lv = g_pvlightvalues[ptricmds[1]];
|
||||
glColor4f( lv[0], lv[1], lv[2], 1.0 );
|
||||
|
||||
av = g_pxformverts[ptricmds[0]];
|
||||
glVertex3f(av[0], av[1], av[2]);
|
||||
}
|
||||
glEnd( );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (i = *(ptricmds++))
|
||||
{
|
||||
if (i < 0)
|
||||
{
|
||||
glBegin( GL_TRIANGLE_FAN );
|
||||
i = -i;
|
||||
}
|
||||
else
|
||||
{
|
||||
glBegin( GL_TRIANGLE_STRIP );
|
||||
}
|
||||
|
||||
|
||||
for( ; i > 0; i--, ptricmds += 4)
|
||||
{
|
||||
// FIX: put these in as integer coords, not floats
|
||||
glTexCoord2f(ptricmds[2]*s, ptricmds[3]*t);
|
||||
|
||||
lv = g_pvlightvalues[ptricmds[1]];
|
||||
glColor4f( lv[0], lv[1], lv[2], 1.0 );
|
||||
|
||||
av = g_pxformverts[ptricmds[0]];
|
||||
glVertex3f(av[0], av[1], av[2]);
|
||||
}
|
||||
glEnd( );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
436
hlsdk/utils/mdlviewer/studio_utils.cpp
Normal file
436
hlsdk/utils/mdlviewer/studio_utils.cpp
Normal file
@ -0,0 +1,436 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, 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.
|
||||
*
|
||||
****/
|
||||
// updates:
|
||||
// 1-4-99 fixed file texture load and file read bug
|
||||
// 2-8-99 fixed demand loaded sequence bug (thanks to Frans 'Otis' Bouma)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1400
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
|
||||
#pragma warning(disable: 4996) // deprecated functions
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <gl\gl.h>
|
||||
#include <gl\glu.h>
|
||||
|
||||
#include "mathlib.h"
|
||||
#include "..\..\engine\studio.h"
|
||||
#include "mdlviewer.h"
|
||||
|
||||
#pragma warning( disable : 4244 ) // double to float
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int g_texnum = 1;
|
||||
|
||||
void StudioModel::UploadTexture(mstudiotexture_t *ptexture, byte *data, byte *pal)
|
||||
{
|
||||
// unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight;
|
||||
int i, j;
|
||||
int row1[256], row2[256], col1[256], col2[256];
|
||||
byte *pix1, *pix2, *pix3, *pix4;
|
||||
byte *tex, *out;
|
||||
|
||||
// convert texture to power of 2
|
||||
int outwidth, outheight;
|
||||
for (outwidth = 1; outwidth < ptexture->width; outwidth <<= 1)
|
||||
;
|
||||
|
||||
if (outwidth > 256)
|
||||
outwidth = 256;
|
||||
|
||||
for (outheight = 1; outheight < ptexture->height; outheight <<= 1)
|
||||
;
|
||||
|
||||
if (outheight > 256)
|
||||
outheight = 256;
|
||||
|
||||
tex = out = (byte *)malloc( outwidth * outheight * 4);
|
||||
|
||||
for (i = 0; i < outwidth; i++)
|
||||
{
|
||||
col1[i] = (i + 0.25) * (ptexture->width / (float)outwidth);
|
||||
col2[i] = (i + 0.75) * (ptexture->width / (float)outwidth);
|
||||
}
|
||||
|
||||
for (i = 0; i < outheight; i++)
|
||||
{
|
||||
row1[i] = (int)((i + 0.25) * (ptexture->height / (float)outheight)) * ptexture->width;
|
||||
row2[i] = (int)((i + 0.75) * (ptexture->height / (float)outheight)) * ptexture->width;
|
||||
}
|
||||
|
||||
// scale down and convert to 32bit RGB
|
||||
for (i=0 ; i<outheight ; i++)
|
||||
{
|
||||
for (j=0 ; j<outwidth ; j++, out += 4)
|
||||
{
|
||||
pix1 = &pal[data[row1[i] + col1[j]] * 3];
|
||||
pix2 = &pal[data[row1[i] + col2[j]] * 3];
|
||||
pix3 = &pal[data[row2[i] + col1[j]] * 3];
|
||||
pix4 = &pal[data[row2[i] + col2[j]] * 3];
|
||||
|
||||
out[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0])>>2;
|
||||
out[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1])>>2;
|
||||
out[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2])>>2;
|
||||
out[3] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, g_texnum );
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, 3/*??*/, outwidth, outheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex );
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
|
||||
// ptexture->width = outwidth;
|
||||
// ptexture->height = outheight;
|
||||
ptexture->index = g_texnum;
|
||||
|
||||
g_texnum++;
|
||||
|
||||
free( tex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
studiohdr_t *StudioModel::LoadModel( char *modelname )
|
||||
{
|
||||
FILE *fp;
|
||||
long size;
|
||||
void *buffer;
|
||||
|
||||
// load the model
|
||||
if( (fp = fopen( modelname, "rb" )) == NULL)
|
||||
{
|
||||
printf("unable to open %s\n", modelname );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fseek( fp, 0, SEEK_END );
|
||||
size = ftell( fp );
|
||||
fseek( fp, 0, SEEK_SET );
|
||||
buffer = malloc( size );
|
||||
fread( buffer, size, 1, fp );
|
||||
|
||||
int i;
|
||||
byte *pin;
|
||||
studiohdr_t *phdr;
|
||||
mstudiotexture_t *ptexture;
|
||||
|
||||
pin = (byte *)buffer;
|
||||
phdr = (studiohdr_t *)pin;
|
||||
|
||||
ptexture = (mstudiotexture_t *)(pin + phdr->textureindex);
|
||||
if (phdr->textureindex != 0)
|
||||
{
|
||||
for (i = 0; i < phdr->numtextures; i++)
|
||||
{
|
||||
// strcpy( name, mod->name );
|
||||
// strcpy( name, ptexture[i].name );
|
||||
UploadTexture( &ptexture[i], pin + ptexture[i].index, pin + ptexture[i].width * ptexture[i].height + ptexture[i].index );
|
||||
}
|
||||
}
|
||||
|
||||
// UNDONE: free texture memory
|
||||
|
||||
fclose( fp );
|
||||
|
||||
return (studiohdr_t *)buffer;
|
||||
}
|
||||
|
||||
|
||||
studioseqhdr_t *StudioModel::LoadDemandSequences( char *modelname )
|
||||
{
|
||||
FILE *fp;
|
||||
long size;
|
||||
void *buffer;
|
||||
|
||||
// load the model
|
||||
if( (fp = fopen( modelname, "rb" )) == NULL)
|
||||
{
|
||||
printf("unable to open %s\n", modelname );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fseek( fp, 0, SEEK_END );
|
||||
size = ftell( fp );
|
||||
fseek( fp, 0, SEEK_SET );
|
||||
buffer = malloc( size );
|
||||
fread( buffer, size, 1, fp );
|
||||
|
||||
fclose( fp );
|
||||
|
||||
return (studioseqhdr_t *)buffer;
|
||||
}
|
||||
|
||||
|
||||
void StudioModel::Init( char *modelname )
|
||||
{
|
||||
m_pstudiohdr = LoadModel( modelname );
|
||||
|
||||
// preload textures
|
||||
if (m_pstudiohdr->numtextures == 0)
|
||||
{
|
||||
char texturename[256];
|
||||
|
||||
strcpy( texturename, modelname );
|
||||
strcpy( &texturename[strlen(texturename) - 4], "T.mdl" );
|
||||
|
||||
m_ptexturehdr = LoadModel( texturename );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ptexturehdr = m_pstudiohdr;
|
||||
}
|
||||
|
||||
// preload animations
|
||||
if (m_pstudiohdr->numseqgroups > 1)
|
||||
{
|
||||
for (int i = 1; i < m_pstudiohdr->numseqgroups; i++)
|
||||
{
|
||||
char seqgroupname[256];
|
||||
|
||||
strcpy( seqgroupname, modelname );
|
||||
sprintf( &seqgroupname[strlen(seqgroupname) - 4], "%02d.mdl", i );
|
||||
|
||||
m_panimhdr[i] = LoadDemandSequences( seqgroupname );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int StudioModel::GetSequence( )
|
||||
{
|
||||
return m_sequence;
|
||||
}
|
||||
|
||||
int StudioModel::SetSequence( int iSequence )
|
||||
{
|
||||
if (iSequence > m_pstudiohdr->numseq)
|
||||
iSequence = 0;
|
||||
if (iSequence < 0)
|
||||
iSequence = m_pstudiohdr->numseq-1;
|
||||
|
||||
m_sequence = iSequence;
|
||||
m_frame = 0;
|
||||
|
||||
return m_sequence;
|
||||
}
|
||||
|
||||
|
||||
void StudioModel::ExtractBbox( float *mins, float *maxs )
|
||||
{
|
||||
mstudioseqdesc_t *pseqdesc;
|
||||
|
||||
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pstudiohdr + m_pstudiohdr->seqindex);
|
||||
|
||||
mins[0] = pseqdesc[ m_sequence ].bbmin[0];
|
||||
mins[1] = pseqdesc[ m_sequence ].bbmin[1];
|
||||
mins[2] = pseqdesc[ m_sequence ].bbmin[2];
|
||||
|
||||
maxs[0] = pseqdesc[ m_sequence ].bbmax[0];
|
||||
maxs[1] = pseqdesc[ m_sequence ].bbmax[1];
|
||||
maxs[2] = pseqdesc[ m_sequence ].bbmax[2];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void StudioModel::GetSequenceInfo( float *pflFrameRate, float *pflGroundSpeed )
|
||||
{
|
||||
mstudioseqdesc_t *pseqdesc;
|
||||
|
||||
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pstudiohdr + m_pstudiohdr->seqindex) + (int)m_sequence;
|
||||
|
||||
if (pseqdesc->numframes > 1)
|
||||
{
|
||||
*pflFrameRate = 256 * pseqdesc->fps / (pseqdesc->numframes - 1);
|
||||
*pflGroundSpeed = sqrt( pseqdesc->linearmovement[0]*pseqdesc->linearmovement[0]+ pseqdesc->linearmovement[1]*pseqdesc->linearmovement[1]+ pseqdesc->linearmovement[2]*pseqdesc->linearmovement[2] );
|
||||
*pflGroundSpeed = *pflGroundSpeed * pseqdesc->fps / (pseqdesc->numframes - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*pflFrameRate = 256.0;
|
||||
*pflGroundSpeed = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float StudioModel::SetController( int iController, float flValue )
|
||||
{
|
||||
mstudiobonecontroller_t *pbonecontroller = (mstudiobonecontroller_t *)((byte *)m_pstudiohdr + m_pstudiohdr->bonecontrollerindex);
|
||||
|
||||
// find first controller that matches the index
|
||||
int i;
|
||||
for (i = 0; i < m_pstudiohdr->numbonecontrollers; i++, pbonecontroller++)
|
||||
{
|
||||
if (pbonecontroller->index == iController)
|
||||
break;
|
||||
}
|
||||
if (i >= m_pstudiohdr->numbonecontrollers)
|
||||
return flValue;
|
||||
|
||||
// wrap 0..360 if it's a rotational controller
|
||||
if (pbonecontroller->type & (STUDIO_XR | STUDIO_YR | STUDIO_ZR))
|
||||
{
|
||||
// ugly hack, invert value if end < start
|
||||
if (pbonecontroller->end < pbonecontroller->start)
|
||||
flValue = -flValue;
|
||||
|
||||
// does the controller not wrap?
|
||||
if (pbonecontroller->start + 359.0 >= pbonecontroller->end)
|
||||
{
|
||||
if (flValue > ((pbonecontroller->start + pbonecontroller->end) / 2.0) + 180)
|
||||
flValue = flValue - 360;
|
||||
if (flValue < ((pbonecontroller->start + pbonecontroller->end) / 2.0) - 180)
|
||||
flValue = flValue + 360;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flValue > 360)
|
||||
flValue = flValue - (int)(flValue / 360.0) * 360.0;
|
||||
else if (flValue < 0)
|
||||
flValue = flValue + (int)((flValue / -360.0) + 1) * 360.0;
|
||||
}
|
||||
}
|
||||
|
||||
int setting = 255 * (flValue - pbonecontroller->start) / (pbonecontroller->end - pbonecontroller->start);
|
||||
|
||||
if (setting < 0) setting = 0;
|
||||
if (setting > 255) setting = 255;
|
||||
m_controller[iController] = setting;
|
||||
|
||||
return setting * (1.0 / 255.0) * (pbonecontroller->end - pbonecontroller->start) + pbonecontroller->start;
|
||||
}
|
||||
|
||||
|
||||
float StudioModel::SetMouth( float flValue )
|
||||
{
|
||||
mstudiobonecontroller_t *pbonecontroller = (mstudiobonecontroller_t *)((byte *)m_pstudiohdr + m_pstudiohdr->bonecontrollerindex);
|
||||
|
||||
// find first controller that matches the mouth
|
||||
for (int i = 0; i < m_pstudiohdr->numbonecontrollers; i++, pbonecontroller++)
|
||||
{
|
||||
if (pbonecontroller->index == 4)
|
||||
break;
|
||||
}
|
||||
|
||||
// wrap 0..360 if it's a rotational controller
|
||||
if (pbonecontroller->type & (STUDIO_XR | STUDIO_YR | STUDIO_ZR))
|
||||
{
|
||||
// ugly hack, invert value if end < start
|
||||
if (pbonecontroller->end < pbonecontroller->start)
|
||||
flValue = -flValue;
|
||||
|
||||
// does the controller not wrap?
|
||||
if (pbonecontroller->start + 359.0 >= pbonecontroller->end)
|
||||
{
|
||||
if (flValue > ((pbonecontroller->start + pbonecontroller->end) / 2.0) + 180)
|
||||
flValue = flValue - 360;
|
||||
if (flValue < ((pbonecontroller->start + pbonecontroller->end) / 2.0) - 180)
|
||||
flValue = flValue + 360;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flValue > 360)
|
||||
flValue = flValue - (int)(flValue / 360.0) * 360.0;
|
||||
else if (flValue < 0)
|
||||
flValue = flValue + (int)((flValue / -360.0) + 1) * 360.0;
|
||||
}
|
||||
}
|
||||
|
||||
int setting = 64 * (flValue - pbonecontroller->start) / (pbonecontroller->end - pbonecontroller->start);
|
||||
|
||||
if (setting < 0) setting = 0;
|
||||
if (setting > 64) setting = 64;
|
||||
m_mouth = setting;
|
||||
|
||||
return setting * (1.0 / 64.0) * (pbonecontroller->end - pbonecontroller->start) + pbonecontroller->start;
|
||||
}
|
||||
|
||||
|
||||
float StudioModel::SetBlending( int iBlender, float flValue )
|
||||
{
|
||||
mstudioseqdesc_t *pseqdesc;
|
||||
|
||||
pseqdesc = (mstudioseqdesc_t *)((byte *)m_pstudiohdr + m_pstudiohdr->seqindex) + (int)m_sequence;
|
||||
|
||||
if (pseqdesc->blendtype[iBlender] == 0)
|
||||
return flValue;
|
||||
|
||||
if (pseqdesc->blendtype[iBlender] & (STUDIO_XR | STUDIO_YR | STUDIO_ZR))
|
||||
{
|
||||
// ugly hack, invert value if end < start
|
||||
if (pseqdesc->blendend[iBlender] < pseqdesc->blendstart[iBlender])
|
||||
flValue = -flValue;
|
||||
|
||||
// does the controller not wrap?
|
||||
if (pseqdesc->blendstart[iBlender] + 359.0 >= pseqdesc->blendend[iBlender])
|
||||
{
|
||||
if (flValue > ((pseqdesc->blendstart[iBlender] + pseqdesc->blendend[iBlender]) / 2.0) + 180)
|
||||
flValue = flValue - 360;
|
||||
if (flValue < ((pseqdesc->blendstart[iBlender] + pseqdesc->blendend[iBlender]) / 2.0) - 180)
|
||||
flValue = flValue + 360;
|
||||
}
|
||||
}
|
||||
|
||||
int setting = 255 * (flValue - pseqdesc->blendstart[iBlender]) / (pseqdesc->blendend[iBlender] - pseqdesc->blendstart[iBlender]);
|
||||
|
||||
if (setting < 0) setting = 0;
|
||||
if (setting > 255) setting = 255;
|
||||
|
||||
m_blending[iBlender] = setting;
|
||||
|
||||
return setting * (1.0 / 255.0) * (pseqdesc->blendend[iBlender] - pseqdesc->blendstart[iBlender]) + pseqdesc->blendstart[iBlender];
|
||||
}
|
||||
|
||||
|
||||
|
||||
int StudioModel::SetBodygroup( int iGroup, int iValue )
|
||||
{
|
||||
if (iGroup > m_pstudiohdr->numbodyparts)
|
||||
return -1;
|
||||
|
||||
mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)m_pstudiohdr + m_pstudiohdr->bodypartindex) + iGroup;
|
||||
|
||||
int iCurrent = (m_bodynum / pbodypart->base) % pbodypart->nummodels;
|
||||
|
||||
if (iValue >= pbodypart->nummodels)
|
||||
return iCurrent;
|
||||
|
||||
m_bodynum = (m_bodynum - (iCurrent * pbodypart->base) + (iValue * pbodypart->base));
|
||||
|
||||
return iValue;
|
||||
}
|
||||
|
||||
|
||||
int StudioModel::SetSkin( int iValue )
|
||||
{
|
||||
if (iValue < m_pstudiohdr->numskinfamilies)
|
||||
{
|
||||
return m_skinnum;
|
||||
}
|
||||
|
||||
m_skinnum = iValue;
|
||||
|
||||
return iValue;
|
||||
}
|
||||
|
Reference in New Issue
Block a user