mirror of
https://github.com/UberGames/lilium-voyager.git
synced 2025-02-21 10:41:08 +00:00
Merge branch 'master' into game/eliteforce
This commit is contained in:
commit
23b9481646
16 changed files with 979 additions and 193 deletions
|
@ -3186,8 +3186,10 @@ static __attribute__ ((format (printf, 2, 3))) void QDECL CL_RefPrintf( int prin
|
||||||
Com_Printf ("%s", msg);
|
Com_Printf ("%s", msg);
|
||||||
} else if ( print_level == PRINT_WARNING ) {
|
} else if ( print_level == PRINT_WARNING ) {
|
||||||
Com_Printf (S_COLOR_YELLOW "%s", msg); // yellow
|
Com_Printf (S_COLOR_YELLOW "%s", msg); // yellow
|
||||||
|
} else if ( print_level == PRINT_ERROR ) {
|
||||||
|
Com_Printf (S_COLOR_RED "%s", msg); // red
|
||||||
} else if ( print_level == PRINT_DEVELOPER ) {
|
} else if ( print_level == PRINT_DEVELOPER ) {
|
||||||
Com_DPrintf (S_COLOR_RED "%s", msg); // red
|
Com_DPrintf (S_COLOR_RED "%s", msg); // red - developer only
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -358,6 +358,7 @@ static int resToRatio[ MAX_RESOLUTIONS ];
|
||||||
|
|
||||||
static char resbuf[ MAX_STRING_CHARS ];
|
static char resbuf[ MAX_STRING_CHARS ];
|
||||||
static const char* detectedResolutions[ MAX_RESOLUTIONS ];
|
static const char* detectedResolutions[ MAX_RESOLUTIONS ];
|
||||||
|
static char currentResolution[ 20 ];
|
||||||
|
|
||||||
static const char** resolutions = builtinResolutions;
|
static const char** resolutions = builtinResolutions;
|
||||||
static qboolean resolutionsDetected = qfalse;
|
static qboolean resolutionsDetected = qfalse;
|
||||||
|
@ -487,7 +488,7 @@ GraphicsOptions_GetResolutions
|
||||||
*/
|
*/
|
||||||
static void GraphicsOptions_GetResolutions( void )
|
static void GraphicsOptions_GetResolutions( void )
|
||||||
{
|
{
|
||||||
Q_strncpyz(resbuf, UI_Cvar_VariableString("r_availableModes"), sizeof(resbuf));
|
trap_Cvar_VariableStringBuffer("r_availableModes", resbuf, sizeof(resbuf));
|
||||||
if(*resbuf)
|
if(*resbuf)
|
||||||
{
|
{
|
||||||
char* s = resbuf;
|
char* s = resbuf;
|
||||||
|
@ -501,11 +502,26 @@ static void GraphicsOptions_GetResolutions( void )
|
||||||
}
|
}
|
||||||
detectedResolutions[ i ] = NULL;
|
detectedResolutions[ i ] = NULL;
|
||||||
|
|
||||||
if( i > 0 )
|
// add custom resolution if not in mode list
|
||||||
|
if ( i < ARRAY_LEN(detectedResolutions)-1 )
|
||||||
{
|
{
|
||||||
resolutions = detectedResolutions;
|
Com_sprintf( currentResolution, sizeof ( currentResolution ), "%dx%d", uis.glconfig.vidWidth, uis.glconfig.vidHeight );
|
||||||
resolutionsDetected = qtrue;
|
|
||||||
|
for( i = 0; detectedResolutions[ i ]; i++ )
|
||||||
|
{
|
||||||
|
if ( strcmp( detectedResolutions[ i ], currentResolution ) == 0 )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( detectedResolutions[ i ] == NULL )
|
||||||
|
{
|
||||||
|
detectedResolutions[ i++ ] = currentResolution;
|
||||||
|
detectedResolutions[ i ] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resolutions = detectedResolutions;
|
||||||
|
resolutionsDetected = qtrue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,28 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
// q_shared.c -- stateless support routines that are included in each code dll
|
// q_shared.c -- stateless support routines that are included in each code dll
|
||||||
#include "q_shared.h"
|
#include "q_shared.h"
|
||||||
|
|
||||||
|
// ^[0-9a-zA-Z]
|
||||||
|
qboolean Q_IsColorString(const char *p) {
|
||||||
|
if (!p)
|
||||||
|
return qfalse;
|
||||||
|
|
||||||
|
if (p[0] != Q_COLOR_ESCAPE)
|
||||||
|
return qfalse;
|
||||||
|
|
||||||
|
if (p[1] == 0)
|
||||||
|
return qfalse;
|
||||||
|
|
||||||
|
// isalnum expects a signed integer in the range -1 (EOF) to 255, or it might assert on undefined behaviour
|
||||||
|
// a dereferenced char pointer has the range -128 to 127, so we just need to rangecheck the negative part
|
||||||
|
if (p[1] < 0)
|
||||||
|
return qfalse;
|
||||||
|
|
||||||
|
if (isalnum(p[1]) == 0)
|
||||||
|
return qfalse;
|
||||||
|
|
||||||
|
return qtrue;
|
||||||
|
}
|
||||||
|
|
||||||
float Com_Clamp( float min, float max, float value ) {
|
float Com_Clamp( float min, float max, float value ) {
|
||||||
if ( value < min ) {
|
if ( value < min ) {
|
||||||
return min;
|
return min;
|
||||||
|
|
|
@ -409,6 +409,8 @@ typedef vec_t vec3_t[3];
|
||||||
typedef vec_t vec4_t[4];
|
typedef vec_t vec4_t[4];
|
||||||
typedef vec_t vec5_t[5];
|
typedef vec_t vec5_t[5];
|
||||||
|
|
||||||
|
typedef vec_t quat_t[4];
|
||||||
|
|
||||||
typedef int fixed4_t;
|
typedef int fixed4_t;
|
||||||
typedef int fixed8_t;
|
typedef int fixed8_t;
|
||||||
typedef int fixed16_t;
|
typedef int fixed16_t;
|
||||||
|
@ -450,7 +452,7 @@ extern vec4_t colorMdGrey;
|
||||||
extern vec4_t colorDkGrey;
|
extern vec4_t colorDkGrey;
|
||||||
|
|
||||||
#define Q_COLOR_ESCAPE '^'
|
#define Q_COLOR_ESCAPE '^'
|
||||||
#define Q_IsColorString(p) ((p) && *(p) == Q_COLOR_ESCAPE && *((p)+1) && isalnum(*((p)+1))) // ^[0-9a-zA-Z]
|
qboolean Q_IsColorString(const char *p); // ^[0-9a-zA-Z]
|
||||||
|
|
||||||
#define COLOR_BLACK '0'
|
#define COLOR_BLACK '0'
|
||||||
#define COLOR_RED '1'
|
#define COLOR_RED '1'
|
||||||
|
@ -619,6 +621,8 @@ typedef struct {
|
||||||
|
|
||||||
#define Byte4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
|
#define Byte4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
|
||||||
|
|
||||||
|
#define QuatCopy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
|
||||||
|
|
||||||
#define SnapVector(v) {v[0]=((int)(v[0]));v[1]=((int)(v[1]));v[2]=((int)(v[2]));}
|
#define SnapVector(v) {v[0]=((int)(v[0]));v[1]=((int)(v[1]));v[2]=((int)(v[2]));}
|
||||||
// just in case you don't want to use the macros
|
// just in case you don't want to use the macros
|
||||||
vec_t _DotProduct( const vec3_t v1, const vec3_t v2 );
|
vec_t _DotProduct( const vec3_t v1, const vec3_t v2 );
|
||||||
|
|
|
@ -590,6 +590,12 @@ typedef struct {
|
||||||
drawVert_t *verts;
|
drawVert_t *verts;
|
||||||
} srfTriangles_t;
|
} srfTriangles_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
vec3_t translate;
|
||||||
|
quat_t rotate;
|
||||||
|
vec3_t scale;
|
||||||
|
} iqmTransform_t;
|
||||||
|
|
||||||
// inter-quake-model
|
// inter-quake-model
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int num_vertexes;
|
int num_vertexes;
|
||||||
|
@ -624,8 +630,9 @@ typedef struct {
|
||||||
|
|
||||||
char *jointNames;
|
char *jointNames;
|
||||||
int *jointParents;
|
int *jointParents;
|
||||||
float *jointMats;
|
float *bindJoints; // [num_joints * 12]
|
||||||
float *poseMats;
|
float *invBindJoints; // [num_joints * 12]
|
||||||
|
iqmTransform_t *poses; // [num_frames * num_poses]
|
||||||
float *bounds;
|
float *bounds;
|
||||||
} iqmData_t;
|
} iqmData_t;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
===========================================================================
|
===========================================================================
|
||||||
Copyright (C) 2011 Thilo Schulz <thilo@tjps.eu>
|
Copyright (C) 2011 Thilo Schulz <thilo@tjps.eu>
|
||||||
Copyright (C) 2011 Matthias Bentrup <matthias.bentrup@googlemail.com>
|
Copyright (C) 2011 Matthias Bentrup <matthias.bentrup@googlemail.com>
|
||||||
|
Copyright (C) 2011-2019 Zack Middleton <zturtleman@gmail.com>
|
||||||
|
|
||||||
This file is part of Quake III Arena source code.
|
This file is part of Quake III Arena source code.
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ static qboolean IQM_CheckRange( iqmHeader_t *header, int offset,
|
||||||
}
|
}
|
||||||
// "multiply" 3x4 matrices, these are assumed to be the top 3 rows
|
// "multiply" 3x4 matrices, these are assumed to be the top 3 rows
|
||||||
// of a 4x4 matrix with the last row = (0 0 0 1)
|
// of a 4x4 matrix with the last row = (0 0 0 1)
|
||||||
static void Matrix34Multiply( float *a, float *b, float *out ) {
|
static void Matrix34Multiply( const float *a, const float *b, float *out ) {
|
||||||
out[ 0] = a[0] * b[0] + a[1] * b[4] + a[ 2] * b[ 8];
|
out[ 0] = a[0] * b[0] + a[1] * b[4] + a[ 2] * b[ 8];
|
||||||
out[ 1] = a[0] * b[1] + a[1] * b[5] + a[ 2] * b[ 9];
|
out[ 1] = a[0] * b[1] + a[1] * b[5] + a[ 2] * b[ 9];
|
||||||
out[ 2] = a[0] * b[2] + a[1] * b[6] + a[ 2] * b[10];
|
out[ 2] = a[0] * b[2] + a[1] * b[6] + a[ 2] * b[10];
|
||||||
|
@ -58,23 +59,7 @@ static void Matrix34Multiply( float *a, float *b, float *out ) {
|
||||||
out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10];
|
out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10];
|
||||||
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
|
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
|
||||||
}
|
}
|
||||||
static void InterpolateMatrix( float *a, float *b, float lerp, float *mat ) {
|
static void JointToMatrix( const quat_t rot, const vec3_t scale, const vec3_t trans,
|
||||||
float unLerp = 1.0f - lerp;
|
|
||||||
|
|
||||||
mat[ 0] = a[ 0] * unLerp + b[ 0] * lerp;
|
|
||||||
mat[ 1] = a[ 1] * unLerp + b[ 1] * lerp;
|
|
||||||
mat[ 2] = a[ 2] * unLerp + b[ 2] * lerp;
|
|
||||||
mat[ 3] = a[ 3] * unLerp + b[ 3] * lerp;
|
|
||||||
mat[ 4] = a[ 4] * unLerp + b[ 4] * lerp;
|
|
||||||
mat[ 5] = a[ 5] * unLerp + b[ 5] * lerp;
|
|
||||||
mat[ 6] = a[ 6] * unLerp + b[ 6] * lerp;
|
|
||||||
mat[ 7] = a[ 7] * unLerp + b[ 7] * lerp;
|
|
||||||
mat[ 8] = a[ 8] * unLerp + b[ 8] * lerp;
|
|
||||||
mat[ 9] = a[ 9] * unLerp + b[ 9] * lerp;
|
|
||||||
mat[10] = a[10] * unLerp + b[10] * lerp;
|
|
||||||
mat[11] = a[11] * unLerp + b[11] * lerp;
|
|
||||||
}
|
|
||||||
static void JointToMatrix( vec4_t rot, vec3_t scale, vec3_t trans,
|
|
||||||
float *mat ) {
|
float *mat ) {
|
||||||
float xx = 2.0f * rot[0] * rot[0];
|
float xx = 2.0f * rot[0] * rot[0];
|
||||||
float yy = 2.0f * rot[1] * rot[1];
|
float yy = 2.0f * rot[1] * rot[1];
|
||||||
|
@ -99,8 +84,7 @@ static void JointToMatrix( vec4_t rot, vec3_t scale, vec3_t trans,
|
||||||
mat[10] = scale[2] * (1.0f - (xx + yy));
|
mat[10] = scale[2] * (1.0f - (xx + yy));
|
||||||
mat[11] = trans[2];
|
mat[11] = trans[2];
|
||||||
}
|
}
|
||||||
static void Matrix34Invert( float *inMat, float *outMat )
|
static void Matrix34Invert( const float *inMat, float *outMat ) {
|
||||||
{
|
|
||||||
vec3_t trans;
|
vec3_t trans;
|
||||||
float invSqrLen, *v;
|
float invSqrLen, *v;
|
||||||
|
|
||||||
|
@ -120,6 +104,61 @@ static void Matrix34Invert( float *inMat, float *outMat )
|
||||||
outMat[ 7] = -DotProduct(outMat + 4, trans);
|
outMat[ 7] = -DotProduct(outMat + 4, trans);
|
||||||
outMat[11] = -DotProduct(outMat + 8, trans);
|
outMat[11] = -DotProduct(outMat + 8, trans);
|
||||||
}
|
}
|
||||||
|
static void QuatSlerp(const quat_t from, const quat_t _to, float fraction, quat_t out) {
|
||||||
|
float angle, cosAngle, sinAngle, backlerp, lerp;
|
||||||
|
quat_t to;
|
||||||
|
|
||||||
|
// cos() of angle
|
||||||
|
cosAngle = from[0] * _to[0] + from[1] * _to[1] + from[2] * _to[2] + from[3] * _to[3];
|
||||||
|
|
||||||
|
// negative handling is needed for taking shortest path (required for model joints)
|
||||||
|
if ( cosAngle < 0.0f ) {
|
||||||
|
cosAngle = -cosAngle;
|
||||||
|
to[0] = - _to[0];
|
||||||
|
to[1] = - _to[1];
|
||||||
|
to[2] = - _to[2];
|
||||||
|
to[3] = - _to[3];
|
||||||
|
} else {
|
||||||
|
QuatCopy( _to, to );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( cosAngle < 0.999999f ) {
|
||||||
|
// spherical lerp (slerp)
|
||||||
|
angle = acosf( cosAngle );
|
||||||
|
sinAngle = sinf( angle );
|
||||||
|
backlerp = sinf( ( 1.0f - fraction ) * angle ) / sinAngle;
|
||||||
|
lerp = sinf( fraction * angle ) / sinAngle;
|
||||||
|
} else {
|
||||||
|
// linear lerp
|
||||||
|
backlerp = 1.0f - fraction;
|
||||||
|
lerp = fraction;
|
||||||
|
}
|
||||||
|
|
||||||
|
out[0] = from[0] * backlerp + to[0] * lerp;
|
||||||
|
out[1] = from[1] * backlerp + to[1] * lerp;
|
||||||
|
out[2] = from[2] * backlerp + to[2] * lerp;
|
||||||
|
out[3] = from[3] * backlerp + to[3] * lerp;
|
||||||
|
}
|
||||||
|
static vec_t QuatNormalize2( const quat_t v, quat_t out) {
|
||||||
|
float length, ilength;
|
||||||
|
|
||||||
|
length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3];
|
||||||
|
|
||||||
|
if (length) {
|
||||||
|
/* writing it this way allows gcc to recognize that rsqrt can be used */
|
||||||
|
ilength = 1/(float)sqrt (length);
|
||||||
|
/* sqrt(length) = length * (1 / sqrt(length)) */
|
||||||
|
length *= ilength;
|
||||||
|
out[0] = v[0]*ilength;
|
||||||
|
out[1] = v[1]*ilength;
|
||||||
|
out[2] = v[2]*ilength;
|
||||||
|
out[3] = v[3]*ilength;
|
||||||
|
} else {
|
||||||
|
out[0] = out[1] = out[2] = out[3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
|
@ -139,7 +178,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
||||||
unsigned short *framedata;
|
unsigned short *framedata;
|
||||||
char *str;
|
char *str;
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
float jointInvMats[IQM_MAX_JOINTS * 12] = {0.0f};
|
iqmTransform_t *transform;
|
||||||
float *mat, *matInv;
|
float *mat, *matInv;
|
||||||
size_t size, joint_names;
|
size_t size, joint_names;
|
||||||
byte *dataPtr;
|
byte *dataPtr;
|
||||||
|
@ -559,10 +598,11 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
||||||
if( header->num_joints ) {
|
if( header->num_joints ) {
|
||||||
size += joint_names; // joint names
|
size += joint_names; // joint names
|
||||||
size += header->num_joints * sizeof(int); // joint parents
|
size += header->num_joints * sizeof(int); // joint parents
|
||||||
size += header->num_joints * 12 * sizeof( float ); // joint mats
|
size += header->num_joints * 12 * sizeof(float); // bind joint matricies
|
||||||
|
size += header->num_joints * 12 * sizeof(float); // inverse bind joint matricies
|
||||||
}
|
}
|
||||||
if( header->num_poses ) {
|
if( header->num_poses ) {
|
||||||
size += header->num_poses * header->num_frames * 12 * sizeof( float ); // pose mats
|
size += header->num_poses * header->num_frames * sizeof(iqmTransform_t); // pose transforms
|
||||||
}
|
}
|
||||||
if( header->ofs_bounds ) {
|
if( header->ofs_bounds ) {
|
||||||
size += header->num_frames * 6 * sizeof(float); // model bounds
|
size += header->num_frames * 6 * sizeof(float); // model bounds
|
||||||
|
@ -633,12 +673,15 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
||||||
iqmData->jointParents = (int*)dataPtr;
|
iqmData->jointParents = (int*)dataPtr;
|
||||||
dataPtr += header->num_joints * sizeof(int); // joint parents
|
dataPtr += header->num_joints * sizeof(int); // joint parents
|
||||||
|
|
||||||
iqmData->jointMats = (float*)dataPtr;
|
iqmData->bindJoints = (float*)dataPtr;
|
||||||
dataPtr += header->num_joints * 12 * sizeof( float ); // joint mats
|
dataPtr += header->num_joints * 12 * sizeof(float); // bind joint matricies
|
||||||
|
|
||||||
|
iqmData->invBindJoints = (float*)dataPtr;
|
||||||
|
dataPtr += header->num_joints * 12 * sizeof(float); // inverse bind joint matricies
|
||||||
}
|
}
|
||||||
if( header->num_poses ) {
|
if( header->num_poses ) {
|
||||||
iqmData->poseMats = (float*)dataPtr;
|
iqmData->poses = (iqmTransform_t*)dataPtr;
|
||||||
dataPtr += header->num_poses * header->num_frames * 12 * sizeof( float ); // pose mats
|
dataPtr += header->num_poses * header->num_frames * sizeof(iqmTransform_t); // pose transforms
|
||||||
}
|
}
|
||||||
if( header->ofs_bounds ) {
|
if( header->ofs_bounds ) {
|
||||||
iqmData->bounds = (float*)dataPtr;
|
iqmData->bounds = (float*)dataPtr;
|
||||||
|
@ -804,22 +847,23 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
||||||
iqmData->jointParents[i] = joint->parent;
|
iqmData->jointParents[i] = joint->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate joint matrices and their inverses
|
// calculate bind joint matrices and their inverses
|
||||||
// joint inverses are needed only until the pose matrices are calculated
|
mat = iqmData->bindJoints;
|
||||||
mat = iqmData->jointMats;
|
matInv = iqmData->invBindJoints;
|
||||||
matInv = jointInvMats;
|
|
||||||
joint = (iqmJoint_t *)((byte *)header + header->ofs_joints);
|
joint = (iqmJoint_t *)((byte *)header + header->ofs_joints);
|
||||||
for( i = 0; i < header->num_joints; i++, joint++ ) {
|
for( i = 0; i < header->num_joints; i++, joint++ ) {
|
||||||
float baseFrame[12], invBaseFrame[12];
|
float baseFrame[12], invBaseFrame[12];
|
||||||
|
|
||||||
|
QuatNormalize2( joint->rotate, joint->rotate );
|
||||||
|
|
||||||
JointToMatrix( joint->rotate, joint->scale, joint->translate, baseFrame );
|
JointToMatrix( joint->rotate, joint->scale, joint->translate, baseFrame );
|
||||||
Matrix34Invert( baseFrame, invBaseFrame );
|
Matrix34Invert( baseFrame, invBaseFrame );
|
||||||
|
|
||||||
if ( joint->parent >= 0 )
|
if ( joint->parent >= 0 )
|
||||||
{
|
{
|
||||||
Matrix34Multiply( iqmData->jointMats + 12 * joint->parent, baseFrame, mat );
|
Matrix34Multiply( iqmData->bindJoints + 12 * joint->parent, baseFrame, mat );
|
||||||
mat += 12;
|
mat += 12;
|
||||||
Matrix34Multiply( invBaseFrame, jointInvMats + 12 * joint->parent, matInv );
|
Matrix34Multiply( invBaseFrame, iqmData->invBindJoints + 12 * joint->parent, matInv );
|
||||||
matInv += 12;
|
matInv += 12;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -834,16 +878,15 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
||||||
|
|
||||||
if( header->num_poses )
|
if( header->num_poses )
|
||||||
{
|
{
|
||||||
// calculate pose matrices
|
// calculate pose transforms
|
||||||
|
transform = iqmData->poses;
|
||||||
framedata = (unsigned short *)((byte *)header + header->ofs_frames);
|
framedata = (unsigned short *)((byte *)header + header->ofs_frames);
|
||||||
mat = iqmData->poseMats;
|
|
||||||
for( i = 0; i < header->num_frames; i++ ) {
|
for( i = 0; i < header->num_frames; i++ ) {
|
||||||
pose = (iqmPose_t *)((byte *)header + header->ofs_poses);
|
pose = (iqmPose_t *)((byte *)header + header->ofs_poses);
|
||||||
for( j = 0; j < header->num_poses; j++, pose++ ) {
|
for( j = 0; j < header->num_poses; j++, pose++, transform++ ) {
|
||||||
vec3_t translate;
|
vec3_t translate;
|
||||||
vec4_t rotate;
|
quat_t rotate;
|
||||||
vec3_t scale;
|
vec3_t scale;
|
||||||
float mat1[12], mat2[12];
|
|
||||||
|
|
||||||
translate[0] = pose->channeloffset[0];
|
translate[0] = pose->channeloffset[0];
|
||||||
if( pose->mask & 0x001)
|
if( pose->mask & 0x001)
|
||||||
|
@ -878,18 +921,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
||||||
if( pose->mask & 0x200)
|
if( pose->mask & 0x200)
|
||||||
scale[2] += *framedata++ * pose->channelscale[9];
|
scale[2] += *framedata++ * pose->channelscale[9];
|
||||||
|
|
||||||
// construct transformation matrix
|
VectorCopy( translate, transform->translate );
|
||||||
JointToMatrix( rotate, scale, translate, mat1 );
|
QuatNormalize2( rotate, transform->rotate );
|
||||||
|
VectorCopy( scale, transform->scale );
|
||||||
if( pose->parent >= 0 ) {
|
|
||||||
Matrix34Multiply( iqmData->jointMats + 12 * pose->parent,
|
|
||||||
mat1, mat2 );
|
|
||||||
} else {
|
|
||||||
Com_Memcpy( mat2, mat1, sizeof(mat1) );
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix34Multiply( mat2, jointInvMats + 12 * j, mat );
|
|
||||||
mat += 12;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1128,37 +1162,59 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) {
|
||||||
|
|
||||||
|
|
||||||
static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
|
static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
|
||||||
float backlerp, float *mat ) {
|
float backlerp, float *poseMats ) {
|
||||||
float *mat1, *mat2;
|
iqmTransform_t relativeJoints[IQM_MAX_JOINTS];
|
||||||
int *joint = data->jointParents;
|
iqmTransform_t *relativeJoint;
|
||||||
int i;
|
const iqmTransform_t *pose;
|
||||||
|
const iqmTransform_t *oldpose;
|
||||||
|
const int *jointParent;
|
||||||
|
const float *invBindMat;
|
||||||
|
float *poseMat, lerp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
relativeJoint = relativeJoints;
|
||||||
|
|
||||||
|
// copy or lerp animation frame pose
|
||||||
if ( oldframe == frame ) {
|
if ( oldframe == frame ) {
|
||||||
mat1 = data->poseMats + 12 * data->num_poses * frame;
|
pose = &data->poses[frame * data->num_poses];
|
||||||
for( i = 0; i < data->num_poses; i++, joint++ ) {
|
for ( i = 0; i < data->num_poses; i++, pose++, relativeJoint++ ) {
|
||||||
if( *joint >= 0 ) {
|
VectorCopy( pose->translate, relativeJoint->translate );
|
||||||
Matrix34Multiply( mat + 12 * *joint,
|
QuatCopy( pose->rotate, relativeJoint->rotate );
|
||||||
mat1 + 12*i, mat + 12*i );
|
VectorCopy( pose->scale, relativeJoint->scale );
|
||||||
} else {
|
|
||||||
Com_Memcpy( mat + 12*i, mat1 + 12*i, 12 * sizeof(float) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mat1 = data->poseMats + 12 * data->num_poses * frame;
|
lerp = 1.0f - backlerp;
|
||||||
mat2 = data->poseMats + 12 * data->num_poses * oldframe;
|
pose = &data->poses[frame * data->num_poses];
|
||||||
|
oldpose = &data->poses[oldframe * data->num_poses];
|
||||||
for( i = 0; i < data->num_poses; i++, joint++ ) {
|
for ( i = 0; i < data->num_poses; i++, oldpose++, pose++, relativeJoint++ ) {
|
||||||
if( *joint >= 0 ) {
|
relativeJoint->translate[0] = oldpose->translate[0] * backlerp + pose->translate[0] * lerp;
|
||||||
float tmpMat[12];
|
relativeJoint->translate[1] = oldpose->translate[1] * backlerp + pose->translate[1] * lerp;
|
||||||
InterpolateMatrix( mat1 + 12*i, mat2 + 12*i,
|
relativeJoint->translate[2] = oldpose->translate[2] * backlerp + pose->translate[2] * lerp;
|
||||||
backlerp, tmpMat );
|
|
||||||
Matrix34Multiply( mat + 12 * *joint,
|
relativeJoint->scale[0] = oldpose->scale[0] * backlerp + pose->scale[0] * lerp;
|
||||||
tmpMat, mat + 12*i );
|
relativeJoint->scale[1] = oldpose->scale[1] * backlerp + pose->scale[1] * lerp;
|
||||||
|
relativeJoint->scale[2] = oldpose->scale[2] * backlerp + pose->scale[2] * lerp;
|
||||||
} else {
|
|
||||||
InterpolateMatrix( mat1 + 12*i, mat2 + 12*i,
|
QuatSlerp( oldpose->rotate, pose->rotate, lerp, relativeJoint->rotate );
|
||||||
backlerp, mat + 12*i );
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// multiply by inverse of bind pose and parent 'pose mat' (bind pose transform matrix)
|
||||||
|
relativeJoint = relativeJoints;
|
||||||
|
jointParent = data->jointParents;
|
||||||
|
invBindMat = data->invBindJoints;
|
||||||
|
poseMat = poseMats;
|
||||||
|
for ( i = 0; i < data->num_poses; i++, relativeJoint++, jointParent++, invBindMat += 12, poseMat += 12 ) {
|
||||||
|
float mat1[12], mat2[12];
|
||||||
|
|
||||||
|
JointToMatrix( relativeJoint->rotate, relativeJoint->scale, relativeJoint->translate, mat1 );
|
||||||
|
|
||||||
|
if ( *jointParent >= 0 ) {
|
||||||
|
Matrix34Multiply( &data->bindJoints[(*jointParent)*12], mat1, mat2 );
|
||||||
|
Matrix34Multiply( mat2, invBindMat, mat1 );
|
||||||
|
Matrix34Multiply( &poseMats[(*jointParent)*12], mat1, poseMat );
|
||||||
|
} else {
|
||||||
|
Matrix34Multiply( mat1, invBindMat, poseMat );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1169,7 +1225,7 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ( data->num_poses == 0 ) {
|
if ( data->num_poses == 0 ) {
|
||||||
Com_Memcpy( mat, data->jointMats, data->num_joints * 12 * sizeof(float) );
|
Com_Memcpy( mat, data->bindJoints, data->num_joints * 12 * sizeof(float) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1181,7 +1237,7 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
|
||||||
|
|
||||||
Com_Memcpy(outmat, mat1, sizeof(outmat));
|
Com_Memcpy(outmat, mat1, sizeof(outmat));
|
||||||
|
|
||||||
Matrix34Multiply( outmat, data->jointMats + 12*i, mat1 );
|
Matrix34Multiply( outmat, data->bindJoints + 12*i, mat1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,19 +1302,20 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
||||||
float *nrmMat = &influenceNrmMat[9*i];
|
float *nrmMat = &influenceNrmMat[9*i];
|
||||||
int j;
|
int j;
|
||||||
float blendWeights[4];
|
float blendWeights[4];
|
||||||
int numWeights;
|
|
||||||
|
|
||||||
for ( numWeights = 0; numWeights < 4; numWeights++ ) {
|
if ( data->blendWeightsType == IQM_FLOAT ) {
|
||||||
if ( data->blendWeightsType == IQM_FLOAT )
|
blendWeights[0] = data->influenceBlendWeights.f[4*influence + 0];
|
||||||
blendWeights[numWeights] = data->influenceBlendWeights.f[4*influence + numWeights];
|
blendWeights[1] = data->influenceBlendWeights.f[4*influence + 1];
|
||||||
else
|
blendWeights[2] = data->influenceBlendWeights.f[4*influence + 2];
|
||||||
blendWeights[numWeights] = (float)data->influenceBlendWeights.b[4*influence + numWeights] / 255.0f;
|
blendWeights[3] = data->influenceBlendWeights.f[4*influence + 3];
|
||||||
|
} else {
|
||||||
if ( blendWeights[numWeights] <= 0.0f )
|
blendWeights[0] = (float)data->influenceBlendWeights.b[4*influence + 0] / 255.0f;
|
||||||
break;
|
blendWeights[1] = (float)data->influenceBlendWeights.b[4*influence + 1] / 255.0f;
|
||||||
|
blendWeights[2] = (float)data->influenceBlendWeights.b[4*influence + 2] / 255.0f;
|
||||||
|
blendWeights[3] = (float)data->influenceBlendWeights.b[4*influence + 3] / 255.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( numWeights == 0 ) {
|
if ( blendWeights[0] <= 0.0f ) {
|
||||||
// no blend joint, use identity matrix.
|
// no blend joint, use identity matrix.
|
||||||
vtxMat[0] = identityMatrix[0];
|
vtxMat[0] = identityMatrix[0];
|
||||||
vtxMat[1] = identityMatrix[1];
|
vtxMat[1] = identityMatrix[1];
|
||||||
|
@ -1288,7 +1345,11 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
||||||
vtxMat[10] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10];
|
vtxMat[10] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10];
|
||||||
vtxMat[11] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11];
|
vtxMat[11] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11];
|
||||||
|
|
||||||
for( j = 1; j < numWeights; j++ ) {
|
for( j = 1; j < 3; j++ ) {
|
||||||
|
if ( blendWeights[j] <= 0.0f ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
vtxMat[0] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 0];
|
vtxMat[0] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 0];
|
||||||
vtxMat[1] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 1];
|
vtxMat[1] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 1];
|
||||||
vtxMat[2] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 2];
|
vtxMat[2] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 2];
|
||||||
|
|
|
@ -143,6 +143,35 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap)
|
||||||
|
|
||||||
return bestDepth;
|
return bestDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float LightRay(vec2 dp, vec2 ds, sampler2D normalMap)
|
||||||
|
{
|
||||||
|
const int linearSearchSteps = 16;
|
||||||
|
|
||||||
|
// current size of search window
|
||||||
|
float size = 1.0 / float(linearSearchSteps);
|
||||||
|
|
||||||
|
// current height from initial texel depth
|
||||||
|
float height = 0.0;
|
||||||
|
|
||||||
|
float startDepth = SampleDepth(normalMap, dp);
|
||||||
|
|
||||||
|
// find a collision or escape
|
||||||
|
for(int i = 0; i < linearSearchSteps - 1; ++i)
|
||||||
|
{
|
||||||
|
height += size;
|
||||||
|
|
||||||
|
if (startDepth < height)
|
||||||
|
return 1.0;
|
||||||
|
|
||||||
|
float t = SampleDepth(normalMap, dp + ds * height);
|
||||||
|
|
||||||
|
if (startDepth > t + height)
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness)
|
vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness)
|
||||||
|
@ -193,6 +222,37 @@ float CalcLightAttenuation(float point, float normDist)
|
||||||
return attenuation;
|
return attenuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_BOX_CUBEMAP_PARALLAX)
|
||||||
|
vec4 hitCube(vec3 ray, vec3 pos, vec3 invSize, float lod, samplerCube tex)
|
||||||
|
{
|
||||||
|
// find any hits on cubemap faces facing the camera
|
||||||
|
vec3 scale = (sign(ray) - pos) / ray;
|
||||||
|
|
||||||
|
// find the nearest hit
|
||||||
|
float minScale = min(min(scale.x, scale.y), scale.z);
|
||||||
|
|
||||||
|
// if the nearest hit is behind the camera, ignore
|
||||||
|
// should not be necessary as long as pos is inside the cube
|
||||||
|
//if (minScale < 0.0)
|
||||||
|
//return vec4(0.0);
|
||||||
|
|
||||||
|
// calculate the hit position, that's our texture coordinates
|
||||||
|
vec3 tc = pos + ray * minScale;
|
||||||
|
|
||||||
|
// if the texture coordinates are outside the cube, ignore
|
||||||
|
// necessary since we're not fading out outside the cube
|
||||||
|
if (any(greaterThan(abs(tc), vec3(1.00001))))
|
||||||
|
return vec4(0.0);
|
||||||
|
|
||||||
|
// fade out when approaching the cubemap edges
|
||||||
|
//vec3 fade3 = abs(pos);
|
||||||
|
//float fade = max(max(fade3.x, fade3.y), fade3.z);
|
||||||
|
//fade = clamp(1.0 - fade, 0.0, 1.0);
|
||||||
|
|
||||||
|
//return vec4(textureCubeLod(tex, tc, lod).rgb * fade, fade);
|
||||||
|
return vec4(textureCubeLod(tex, tc, lod).rgb, 1.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
@ -222,7 +282,7 @@ void main()
|
||||||
vec2 texCoords = var_TexCoords.xy;
|
vec2 texCoords = var_TexCoords.xy;
|
||||||
|
|
||||||
#if defined(USE_PARALLAXMAP)
|
#if defined(USE_PARALLAXMAP)
|
||||||
vec3 offsetDir = viewDir * tangentToWorld;
|
vec3 offsetDir = E * tangentToWorld;
|
||||||
|
|
||||||
offsetDir.xy *= -u_NormalScale.a / offsetDir.z;
|
offsetDir.xy *= -u_NormalScale.a / offsetDir.z;
|
||||||
|
|
||||||
|
@ -289,6 +349,13 @@ void main()
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_PARALLAXMAP) && defined(USE_PARALLAXMAP_SHADOWS)
|
||||||
|
offsetDir = L * tangentToWorld;
|
||||||
|
offsetDir.xy *= u_NormalScale.a / offsetDir.z;
|
||||||
|
lightColor *= LightRay(texCoords, offsetDir.xy, u_NormalMap);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(USE_LIGHT_VECTOR)
|
#if !defined(USE_LIGHT_VECTOR)
|
||||||
ambientColor = lightColor;
|
ambientColor = lightColor;
|
||||||
float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0);
|
float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0);
|
||||||
|
@ -374,7 +441,11 @@ void main()
|
||||||
// from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
|
// from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
|
||||||
vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir;
|
vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir;
|
||||||
|
|
||||||
|
#if defined(USE_BOX_CUBEMAP_PARALLAX)
|
||||||
|
vec3 cubeLightColor = hitCube(R * u_CubeMapInfo.w, parallax, u_CubeMapInfo.www, ROUGHNESS_MIPS * roughness, u_CubeMap).rgb * u_EnableTextures.w;
|
||||||
|
#else
|
||||||
vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, ROUGHNESS_MIPS * roughness).rgb * u_EnableTextures.w;
|
vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, ROUGHNESS_MIPS * roughness).rgb * u_EnableTextures.w;
|
||||||
|
#endif
|
||||||
|
|
||||||
// normalize cubemap based on last roughness mip (~diffuse)
|
// normalize cubemap based on last roughness mip (~diffuse)
|
||||||
// multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation
|
// multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation
|
||||||
|
@ -423,6 +494,12 @@ void main()
|
||||||
// enable when point lights are supported as primary lights
|
// enable when point lights are supported as primary lights
|
||||||
//lightColor *= CalcLightAttenuation(float(u_PrimaryLightDir.w > 0.0), u_PrimaryLightDir.w / sqrLightDist);
|
//lightColor *= CalcLightAttenuation(float(u_PrimaryLightDir.w > 0.0), u_PrimaryLightDir.w / sqrLightDist);
|
||||||
|
|
||||||
|
#if defined(USE_PARALLAXMAP) && defined(USE_PARALLAXMAP_SHADOWS)
|
||||||
|
offsetDir = L2 * tangentToWorld;
|
||||||
|
offsetDir.xy *= u_NormalScale.a / offsetDir.z;
|
||||||
|
lightColor *= LightRay(texCoords, offsetDir.xy, u_NormalMap);
|
||||||
|
#endif
|
||||||
|
|
||||||
gl_FragColor.rgb += lightColor * reflectance * NL2;
|
gl_FragColor.rgb += lightColor * reflectance * NL2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1122,6 +1122,9 @@ void GLSL_InitGPUShaders(void)
|
||||||
Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n");
|
Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n");
|
||||||
if (r_parallaxMapping->integer > 1)
|
if (r_parallaxMapping->integer > 1)
|
||||||
Q_strcat(extradefines, 1024, "#define USE_RELIEFMAP\n");
|
Q_strcat(extradefines, 1024, "#define USE_RELIEFMAP\n");
|
||||||
|
|
||||||
|
if (r_parallaxMapShadows->integer)
|
||||||
|
Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP_SHADOWS\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1129,9 +1132,15 @@ void GLSL_InitGPUShaders(void)
|
||||||
Q_strcat(extradefines, 1024, "#define USE_SPECULARMAP\n");
|
Q_strcat(extradefines, 1024, "#define USE_SPECULARMAP\n");
|
||||||
|
|
||||||
if (r_cubeMapping->integer)
|
if (r_cubeMapping->integer)
|
||||||
|
{
|
||||||
Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n");
|
Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n");
|
||||||
|
if (r_cubeMapping->integer == 2)
|
||||||
|
Q_strcat(extradefines, 1024, "#define USE_BOX_CUBEMAP_PARALLAX\n");
|
||||||
|
}
|
||||||
else if (r_deluxeSpecular->value > 0.000001f)
|
else if (r_deluxeSpecular->value > 0.000001f)
|
||||||
|
{
|
||||||
Q_strcat(extradefines, 1024, va("#define r_deluxeSpecular %f\n", r_deluxeSpecular->value));
|
Q_strcat(extradefines, 1024, va("#define r_deluxeSpecular %f\n", r_deluxeSpecular->value));
|
||||||
|
}
|
||||||
|
|
||||||
switch (r_glossType->integer)
|
switch (r_glossType->integer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -134,6 +134,7 @@ cvar_t *r_normalMapping;
|
||||||
cvar_t *r_specularMapping;
|
cvar_t *r_specularMapping;
|
||||||
cvar_t *r_deluxeMapping;
|
cvar_t *r_deluxeMapping;
|
||||||
cvar_t *r_parallaxMapping;
|
cvar_t *r_parallaxMapping;
|
||||||
|
cvar_t *r_parallaxMapShadows;
|
||||||
cvar_t *r_cubeMapping;
|
cvar_t *r_cubeMapping;
|
||||||
cvar_t *r_cubemapSize;
|
cvar_t *r_cubemapSize;
|
||||||
cvar_t *r_deluxeSpecular;
|
cvar_t *r_deluxeSpecular;
|
||||||
|
@ -291,6 +292,12 @@ static void InitOpenGL( void )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for GLSL function textureCubeLod()
|
||||||
|
if ( r_cubeMapping->integer && !QGL_VERSION_ATLEAST( 3, 0 ) ) {
|
||||||
|
ri.Printf( PRINT_WARNING, "WARNING: Disabled r_cubeMapping because it requires OpenGL 3.0\n" );
|
||||||
|
ri.Cvar_Set( "r_cubeMapping", "0" );
|
||||||
|
}
|
||||||
|
|
||||||
// set default state
|
// set default state
|
||||||
GL_SetDefaultState();
|
GL_SetDefaultState();
|
||||||
}
|
}
|
||||||
|
@ -1246,6 +1253,7 @@ void R_Register( void )
|
||||||
r_specularMapping = ri.Cvar_Get( "r_specularMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
r_specularMapping = ri.Cvar_Get( "r_specularMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||||
r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
|
||||||
r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||||
|
r_parallaxMapShadows = ri.Cvar_Get( "r_parallaxMapShadows", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||||
r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||||
r_cubemapSize = ri.Cvar_Get( "r_cubemapSize", "128", CVAR_ARCHIVE | CVAR_LATCH );
|
r_cubemapSize = ri.Cvar_Get( "r_cubemapSize", "128", CVAR_ARCHIVE | CVAR_LATCH );
|
||||||
r_deluxeSpecular = ri.Cvar_Get("r_deluxeSpecular", "0.3", CVAR_ARCHIVE | CVAR_LATCH);
|
r_deluxeSpecular = ri.Cvar_Get("r_deluxeSpecular", "0.3", CVAR_ARCHIVE | CVAR_LATCH);
|
||||||
|
|
|
@ -955,6 +955,12 @@ typedef struct srfBspSurface_s
|
||||||
float *heightLodError;
|
float *heightLodError;
|
||||||
} srfBspSurface_t;
|
} srfBspSurface_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
vec3_t translate;
|
||||||
|
quat_t rotate;
|
||||||
|
vec3_t scale;
|
||||||
|
} iqmTransform_t;
|
||||||
|
|
||||||
// inter-quake-model
|
// inter-quake-model
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int num_vertexes;
|
int num_vertexes;
|
||||||
|
@ -989,8 +995,9 @@ typedef struct {
|
||||||
|
|
||||||
char *jointNames;
|
char *jointNames;
|
||||||
int *jointParents;
|
int *jointParents;
|
||||||
float *jointMats;
|
float *bindJoints; // [num_joints * 12]
|
||||||
float *poseMats;
|
float *invBindJoints; // [num_joints * 12]
|
||||||
|
iqmTransform_t *poses; // [num_frames * num_poses]
|
||||||
float *bounds;
|
float *bounds;
|
||||||
|
|
||||||
int numVaoSurfaces;
|
int numVaoSurfaces;
|
||||||
|
@ -1771,6 +1778,7 @@ extern cvar_t *r_normalMapping;
|
||||||
extern cvar_t *r_specularMapping;
|
extern cvar_t *r_specularMapping;
|
||||||
extern cvar_t *r_deluxeMapping;
|
extern cvar_t *r_deluxeMapping;
|
||||||
extern cvar_t *r_parallaxMapping;
|
extern cvar_t *r_parallaxMapping;
|
||||||
|
extern cvar_t *r_parallaxMapShadows;
|
||||||
extern cvar_t *r_cubeMapping;
|
extern cvar_t *r_cubeMapping;
|
||||||
extern cvar_t *r_cubemapSize;
|
extern cvar_t *r_cubemapSize;
|
||||||
extern cvar_t *r_deluxeSpecular;
|
extern cvar_t *r_deluxeSpecular;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
===========================================================================
|
===========================================================================
|
||||||
Copyright (C) 2011 Thilo Schulz <thilo@tjps.eu>
|
Copyright (C) 2011 Thilo Schulz <thilo@tjps.eu>
|
||||||
Copyright (C) 2011 Matthias Bentrup <matthias.bentrup@googlemail.com>
|
Copyright (C) 2011 Matthias Bentrup <matthias.bentrup@googlemail.com>
|
||||||
|
Copyright (C) 2011-2019 Zack Middleton <zturtleman@gmail.com>
|
||||||
|
|
||||||
This file is part of Quake III Arena source code.
|
This file is part of Quake III Arena source code.
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ static qboolean IQM_CheckRange( iqmHeader_t *header, int offset,
|
||||||
}
|
}
|
||||||
// "multiply" 3x4 matrices, these are assumed to be the top 3 rows
|
// "multiply" 3x4 matrices, these are assumed to be the top 3 rows
|
||||||
// of a 4x4 matrix with the last row = (0 0 0 1)
|
// of a 4x4 matrix with the last row = (0 0 0 1)
|
||||||
static void Matrix34Multiply( float *a, float *b, float *out ) {
|
static void Matrix34Multiply( const float *a, const float *b, float *out ) {
|
||||||
out[ 0] = a[0] * b[0] + a[1] * b[4] + a[ 2] * b[ 8];
|
out[ 0] = a[0] * b[0] + a[1] * b[4] + a[ 2] * b[ 8];
|
||||||
out[ 1] = a[0] * b[1] + a[1] * b[5] + a[ 2] * b[ 9];
|
out[ 1] = a[0] * b[1] + a[1] * b[5] + a[ 2] * b[ 9];
|
||||||
out[ 2] = a[0] * b[2] + a[1] * b[6] + a[ 2] * b[10];
|
out[ 2] = a[0] * b[2] + a[1] * b[6] + a[ 2] * b[10];
|
||||||
|
@ -58,23 +59,7 @@ static void Matrix34Multiply( float *a, float *b, float *out ) {
|
||||||
out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10];
|
out[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10];
|
||||||
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
|
out[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11];
|
||||||
}
|
}
|
||||||
static void InterpolateMatrix( float *a, float *b, float lerp, float *mat ) {
|
static void JointToMatrix( const quat_t rot, const vec3_t scale, const vec3_t trans,
|
||||||
float unLerp = 1.0f - lerp;
|
|
||||||
|
|
||||||
mat[ 0] = a[ 0] * unLerp + b[ 0] * lerp;
|
|
||||||
mat[ 1] = a[ 1] * unLerp + b[ 1] * lerp;
|
|
||||||
mat[ 2] = a[ 2] * unLerp + b[ 2] * lerp;
|
|
||||||
mat[ 3] = a[ 3] * unLerp + b[ 3] * lerp;
|
|
||||||
mat[ 4] = a[ 4] * unLerp + b[ 4] * lerp;
|
|
||||||
mat[ 5] = a[ 5] * unLerp + b[ 5] * lerp;
|
|
||||||
mat[ 6] = a[ 6] * unLerp + b[ 6] * lerp;
|
|
||||||
mat[ 7] = a[ 7] * unLerp + b[ 7] * lerp;
|
|
||||||
mat[ 8] = a[ 8] * unLerp + b[ 8] * lerp;
|
|
||||||
mat[ 9] = a[ 9] * unLerp + b[ 9] * lerp;
|
|
||||||
mat[10] = a[10] * unLerp + b[10] * lerp;
|
|
||||||
mat[11] = a[11] * unLerp + b[11] * lerp;
|
|
||||||
}
|
|
||||||
static void JointToMatrix( vec4_t rot, vec3_t scale, vec3_t trans,
|
|
||||||
float *mat ) {
|
float *mat ) {
|
||||||
float xx = 2.0f * rot[0] * rot[0];
|
float xx = 2.0f * rot[0] * rot[0];
|
||||||
float yy = 2.0f * rot[1] * rot[1];
|
float yy = 2.0f * rot[1] * rot[1];
|
||||||
|
@ -99,8 +84,7 @@ static void JointToMatrix( vec4_t rot, vec3_t scale, vec3_t trans,
|
||||||
mat[10] = scale[2] * (1.0f - (xx + yy));
|
mat[10] = scale[2] * (1.0f - (xx + yy));
|
||||||
mat[11] = trans[2];
|
mat[11] = trans[2];
|
||||||
}
|
}
|
||||||
static void Matrix34Invert( float *inMat, float *outMat )
|
static void Matrix34Invert( const float *inMat, float *outMat ) {
|
||||||
{
|
|
||||||
vec3_t trans;
|
vec3_t trans;
|
||||||
float invSqrLen, *v;
|
float invSqrLen, *v;
|
||||||
|
|
||||||
|
@ -120,6 +104,61 @@ static void Matrix34Invert( float *inMat, float *outMat )
|
||||||
outMat[ 7] = -DotProduct(outMat + 4, trans);
|
outMat[ 7] = -DotProduct(outMat + 4, trans);
|
||||||
outMat[11] = -DotProduct(outMat + 8, trans);
|
outMat[11] = -DotProduct(outMat + 8, trans);
|
||||||
}
|
}
|
||||||
|
static void QuatSlerp(const quat_t from, const quat_t _to, float fraction, quat_t out) {
|
||||||
|
float angle, cosAngle, sinAngle, backlerp, lerp;
|
||||||
|
quat_t to;
|
||||||
|
|
||||||
|
// cos() of angle
|
||||||
|
cosAngle = from[0] * _to[0] + from[1] * _to[1] + from[2] * _to[2] + from[3] * _to[3];
|
||||||
|
|
||||||
|
// negative handling is needed for taking shortest path (required for model joints)
|
||||||
|
if ( cosAngle < 0.0f ) {
|
||||||
|
cosAngle = -cosAngle;
|
||||||
|
to[0] = - _to[0];
|
||||||
|
to[1] = - _to[1];
|
||||||
|
to[2] = - _to[2];
|
||||||
|
to[3] = - _to[3];
|
||||||
|
} else {
|
||||||
|
QuatCopy( _to, to );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( cosAngle < 0.999999f ) {
|
||||||
|
// spherical lerp (slerp)
|
||||||
|
angle = acosf( cosAngle );
|
||||||
|
sinAngle = sinf( angle );
|
||||||
|
backlerp = sinf( ( 1.0f - fraction ) * angle ) / sinAngle;
|
||||||
|
lerp = sinf( fraction * angle ) / sinAngle;
|
||||||
|
} else {
|
||||||
|
// linear lerp
|
||||||
|
backlerp = 1.0f - fraction;
|
||||||
|
lerp = fraction;
|
||||||
|
}
|
||||||
|
|
||||||
|
out[0] = from[0] * backlerp + to[0] * lerp;
|
||||||
|
out[1] = from[1] * backlerp + to[1] * lerp;
|
||||||
|
out[2] = from[2] * backlerp + to[2] * lerp;
|
||||||
|
out[3] = from[3] * backlerp + to[3] * lerp;
|
||||||
|
}
|
||||||
|
static vec_t QuatNormalize2( const quat_t v, quat_t out) {
|
||||||
|
float length, ilength;
|
||||||
|
|
||||||
|
length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3];
|
||||||
|
|
||||||
|
if (length) {
|
||||||
|
/* writing it this way allows gcc to recognize that rsqrt can be used */
|
||||||
|
ilength = 1/(float)sqrt (length);
|
||||||
|
/* sqrt(length) = length * (1 / sqrt(length)) */
|
||||||
|
length *= ilength;
|
||||||
|
out[0] = v[0]*ilength;
|
||||||
|
out[1] = v[1]*ilength;
|
||||||
|
out[2] = v[2]*ilength;
|
||||||
|
out[3] = v[3]*ilength;
|
||||||
|
} else {
|
||||||
|
out[0] = out[1] = out[2] = out[3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
|
@ -139,7 +178,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
||||||
unsigned short *framedata;
|
unsigned short *framedata;
|
||||||
char *str;
|
char *str;
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
float jointInvMats[IQM_MAX_JOINTS * 12] = {0.0f};
|
iqmTransform_t *transform;
|
||||||
float *mat, *matInv;
|
float *mat, *matInv;
|
||||||
size_t size, joint_names;
|
size_t size, joint_names;
|
||||||
byte *dataPtr;
|
byte *dataPtr;
|
||||||
|
@ -562,10 +601,11 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
||||||
if( header->num_joints ) {
|
if( header->num_joints ) {
|
||||||
size += joint_names; // joint names
|
size += joint_names; // joint names
|
||||||
size += header->num_joints * sizeof(int); // joint parents
|
size += header->num_joints * sizeof(int); // joint parents
|
||||||
size += header->num_joints * 12 * sizeof( float ); // joint mats
|
size += header->num_joints * 12 * sizeof(float); // bind joint matricies
|
||||||
|
size += header->num_joints * 12 * sizeof(float); // inverse bind joint matricies
|
||||||
}
|
}
|
||||||
if( header->num_poses ) {
|
if( header->num_poses ) {
|
||||||
size += header->num_poses * header->num_frames * 12 * sizeof( float ); // pose mats
|
size += header->num_poses * header->num_frames * sizeof(iqmTransform_t); // pose transforms
|
||||||
}
|
}
|
||||||
if( header->ofs_bounds ) {
|
if( header->ofs_bounds ) {
|
||||||
size += header->num_frames * 6 * sizeof(float); // model bounds
|
size += header->num_frames * 6 * sizeof(float); // model bounds
|
||||||
|
@ -636,12 +676,15 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
||||||
iqmData->jointParents = (int*)dataPtr;
|
iqmData->jointParents = (int*)dataPtr;
|
||||||
dataPtr += header->num_joints * sizeof(int); // joint parents
|
dataPtr += header->num_joints * sizeof(int); // joint parents
|
||||||
|
|
||||||
iqmData->jointMats = (float*)dataPtr;
|
iqmData->bindJoints = (float*)dataPtr;
|
||||||
dataPtr += header->num_joints * 12 * sizeof( float ); // joint mats
|
dataPtr += header->num_joints * 12 * sizeof(float); // bind joint matricies
|
||||||
|
|
||||||
|
iqmData->invBindJoints = (float*)dataPtr;
|
||||||
|
dataPtr += header->num_joints * 12 * sizeof(float); // inverse bind joint matricies
|
||||||
}
|
}
|
||||||
if( header->num_poses ) {
|
if( header->num_poses ) {
|
||||||
iqmData->poseMats = (float*)dataPtr;
|
iqmData->poses = (iqmTransform_t*)dataPtr;
|
||||||
dataPtr += header->num_poses * header->num_frames * 12 * sizeof( float ); // pose mats
|
dataPtr += header->num_poses * header->num_frames * sizeof(iqmTransform_t); // pose transforms
|
||||||
}
|
}
|
||||||
if( header->ofs_bounds ) {
|
if( header->ofs_bounds ) {
|
||||||
iqmData->bounds = (float*)dataPtr;
|
iqmData->bounds = (float*)dataPtr;
|
||||||
|
@ -807,22 +850,23 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
||||||
iqmData->jointParents[i] = joint->parent;
|
iqmData->jointParents[i] = joint->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate joint matrices and their inverses
|
// calculate bind joint matrices and their inverses
|
||||||
// joint inverses are needed only until the pose matrices are calculated
|
mat = iqmData->bindJoints;
|
||||||
mat = iqmData->jointMats;
|
matInv = iqmData->invBindJoints;
|
||||||
matInv = jointInvMats;
|
|
||||||
joint = (iqmJoint_t *)((byte *)header + header->ofs_joints);
|
joint = (iqmJoint_t *)((byte *)header + header->ofs_joints);
|
||||||
for( i = 0; i < header->num_joints; i++, joint++ ) {
|
for( i = 0; i < header->num_joints; i++, joint++ ) {
|
||||||
float baseFrame[12], invBaseFrame[12];
|
float baseFrame[12], invBaseFrame[12];
|
||||||
|
|
||||||
|
QuatNormalize2( joint->rotate, joint->rotate );
|
||||||
|
|
||||||
JointToMatrix( joint->rotate, joint->scale, joint->translate, baseFrame );
|
JointToMatrix( joint->rotate, joint->scale, joint->translate, baseFrame );
|
||||||
Matrix34Invert( baseFrame, invBaseFrame );
|
Matrix34Invert( baseFrame, invBaseFrame );
|
||||||
|
|
||||||
if ( joint->parent >= 0 )
|
if ( joint->parent >= 0 )
|
||||||
{
|
{
|
||||||
Matrix34Multiply( iqmData->jointMats + 12 * joint->parent, baseFrame, mat );
|
Matrix34Multiply( iqmData->bindJoints + 12 * joint->parent, baseFrame, mat );
|
||||||
mat += 12;
|
mat += 12;
|
||||||
Matrix34Multiply( invBaseFrame, jointInvMats + 12 * joint->parent, matInv );
|
Matrix34Multiply( invBaseFrame, iqmData->invBindJoints + 12 * joint->parent, matInv );
|
||||||
matInv += 12;
|
matInv += 12;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -837,16 +881,15 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
||||||
|
|
||||||
if( header->num_poses )
|
if( header->num_poses )
|
||||||
{
|
{
|
||||||
// calculate pose matrices
|
// calculate pose transforms
|
||||||
|
transform = iqmData->poses;
|
||||||
framedata = (unsigned short *)((byte *)header + header->ofs_frames);
|
framedata = (unsigned short *)((byte *)header + header->ofs_frames);
|
||||||
mat = iqmData->poseMats;
|
|
||||||
for( i = 0; i < header->num_frames; i++ ) {
|
for( i = 0; i < header->num_frames; i++ ) {
|
||||||
pose = (iqmPose_t *)((byte *)header + header->ofs_poses);
|
pose = (iqmPose_t *)((byte *)header + header->ofs_poses);
|
||||||
for( j = 0; j < header->num_poses; j++, pose++ ) {
|
for( j = 0; j < header->num_poses; j++, pose++, transform++ ) {
|
||||||
vec3_t translate;
|
vec3_t translate;
|
||||||
vec4_t rotate;
|
quat_t rotate;
|
||||||
vec3_t scale;
|
vec3_t scale;
|
||||||
float mat1[12], mat2[12];
|
|
||||||
|
|
||||||
translate[0] = pose->channeloffset[0];
|
translate[0] = pose->channeloffset[0];
|
||||||
if( pose->mask & 0x001)
|
if( pose->mask & 0x001)
|
||||||
|
@ -881,18 +924,9 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
|
||||||
if( pose->mask & 0x200)
|
if( pose->mask & 0x200)
|
||||||
scale[2] += *framedata++ * pose->channelscale[9];
|
scale[2] += *framedata++ * pose->channelscale[9];
|
||||||
|
|
||||||
// construct transformation matrix
|
VectorCopy( translate, transform->translate );
|
||||||
JointToMatrix( rotate, scale, translate, mat1 );
|
QuatNormalize2( rotate, transform->rotate );
|
||||||
|
VectorCopy( scale, transform->scale );
|
||||||
if( pose->parent >= 0 ) {
|
|
||||||
Matrix34Multiply( iqmData->jointMats + 12 * pose->parent,
|
|
||||||
mat1, mat2 );
|
|
||||||
} else {
|
|
||||||
Com_Memcpy( mat2, mat1, sizeof(mat1) );
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix34Multiply( mat2, jointInvMats + 12 * j, mat );
|
|
||||||
mat += 12;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1306,37 +1340,59 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) {
|
||||||
|
|
||||||
|
|
||||||
static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
|
static void ComputePoseMats( iqmData_t *data, int frame, int oldframe,
|
||||||
float backlerp, float *mat ) {
|
float backlerp, float *poseMats ) {
|
||||||
float *mat1, *mat2;
|
iqmTransform_t relativeJoints[IQM_MAX_JOINTS];
|
||||||
int *joint = data->jointParents;
|
iqmTransform_t *relativeJoint;
|
||||||
int i;
|
const iqmTransform_t *pose;
|
||||||
|
const iqmTransform_t *oldpose;
|
||||||
|
const int *jointParent;
|
||||||
|
const float *invBindMat;
|
||||||
|
float *poseMat, lerp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
relativeJoint = relativeJoints;
|
||||||
|
|
||||||
|
// copy or lerp animation frame pose
|
||||||
if ( oldframe == frame ) {
|
if ( oldframe == frame ) {
|
||||||
mat1 = data->poseMats + 12 * data->num_poses * frame;
|
pose = &data->poses[frame * data->num_poses];
|
||||||
for( i = 0; i < data->num_poses; i++, joint++ ) {
|
for ( i = 0; i < data->num_poses; i++, pose++, relativeJoint++ ) {
|
||||||
if( *joint >= 0 ) {
|
VectorCopy( pose->translate, relativeJoint->translate );
|
||||||
Matrix34Multiply( mat + 12 * *joint,
|
QuatCopy( pose->rotate, relativeJoint->rotate );
|
||||||
mat1 + 12*i, mat + 12*i );
|
VectorCopy( pose->scale, relativeJoint->scale );
|
||||||
} else {
|
|
||||||
Com_Memcpy( mat + 12*i, mat1 + 12*i, 12 * sizeof(float) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mat1 = data->poseMats + 12 * data->num_poses * frame;
|
lerp = 1.0f - backlerp;
|
||||||
mat2 = data->poseMats + 12 * data->num_poses * oldframe;
|
pose = &data->poses[frame * data->num_poses];
|
||||||
|
oldpose = &data->poses[oldframe * data->num_poses];
|
||||||
for( i = 0; i < data->num_poses; i++, joint++ ) {
|
for ( i = 0; i < data->num_poses; i++, oldpose++, pose++, relativeJoint++ ) {
|
||||||
if( *joint >= 0 ) {
|
relativeJoint->translate[0] = oldpose->translate[0] * backlerp + pose->translate[0] * lerp;
|
||||||
float tmpMat[12];
|
relativeJoint->translate[1] = oldpose->translate[1] * backlerp + pose->translate[1] * lerp;
|
||||||
InterpolateMatrix( mat1 + 12*i, mat2 + 12*i,
|
relativeJoint->translate[2] = oldpose->translate[2] * backlerp + pose->translate[2] * lerp;
|
||||||
backlerp, tmpMat );
|
|
||||||
Matrix34Multiply( mat + 12 * *joint,
|
relativeJoint->scale[0] = oldpose->scale[0] * backlerp + pose->scale[0] * lerp;
|
||||||
tmpMat, mat + 12*i );
|
relativeJoint->scale[1] = oldpose->scale[1] * backlerp + pose->scale[1] * lerp;
|
||||||
|
relativeJoint->scale[2] = oldpose->scale[2] * backlerp + pose->scale[2] * lerp;
|
||||||
} else {
|
|
||||||
InterpolateMatrix( mat1 + 12*i, mat2 + 12*i,
|
QuatSlerp( oldpose->rotate, pose->rotate, lerp, relativeJoint->rotate );
|
||||||
backlerp, mat + 12*i );
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// multiply by inverse of bind pose and parent 'pose mat' (bind pose transform matrix)
|
||||||
|
relativeJoint = relativeJoints;
|
||||||
|
jointParent = data->jointParents;
|
||||||
|
invBindMat = data->invBindJoints;
|
||||||
|
poseMat = poseMats;
|
||||||
|
for ( i = 0; i < data->num_poses; i++, relativeJoint++, jointParent++, invBindMat += 12, poseMat += 12 ) {
|
||||||
|
float mat1[12], mat2[12];
|
||||||
|
|
||||||
|
JointToMatrix( relativeJoint->rotate, relativeJoint->scale, relativeJoint->translate, mat1 );
|
||||||
|
|
||||||
|
if ( *jointParent >= 0 ) {
|
||||||
|
Matrix34Multiply( &data->bindJoints[(*jointParent)*12], mat1, mat2 );
|
||||||
|
Matrix34Multiply( mat2, invBindMat, mat1 );
|
||||||
|
Matrix34Multiply( &poseMats[(*jointParent)*12], mat1, poseMat );
|
||||||
|
} else {
|
||||||
|
Matrix34Multiply( mat1, invBindMat, poseMat );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1347,7 +1403,7 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ( data->num_poses == 0 ) {
|
if ( data->num_poses == 0 ) {
|
||||||
Com_Memcpy( mat, data->jointMats, data->num_joints * 12 * sizeof(float) );
|
Com_Memcpy( mat, data->bindJoints, data->num_joints * 12 * sizeof(float) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1359,7 +1415,7 @@ static void ComputeJointMats( iqmData_t *data, int frame, int oldframe,
|
||||||
|
|
||||||
Com_Memcpy(outmat, mat1, sizeof(outmat));
|
Com_Memcpy(outmat, mat1, sizeof(outmat));
|
||||||
|
|
||||||
Matrix34Multiply( outmat, data->jointMats + 12*i, mat1 );
|
Matrix34Multiply( outmat, data->bindJoints + 12*i, mat1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1428,19 +1484,20 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
||||||
float *nrmMat = &influenceNrmMat[9*i];
|
float *nrmMat = &influenceNrmMat[9*i];
|
||||||
int j;
|
int j;
|
||||||
float blendWeights[4];
|
float blendWeights[4];
|
||||||
int numWeights;
|
|
||||||
|
|
||||||
for ( numWeights = 0; numWeights < 4; numWeights++ ) {
|
if ( data->blendWeightsType == IQM_FLOAT ) {
|
||||||
if ( data->blendWeightsType == IQM_FLOAT )
|
blendWeights[0] = data->influenceBlendWeights.f[4*influence + 0];
|
||||||
blendWeights[numWeights] = data->influenceBlendWeights.f[4*influence + numWeights];
|
blendWeights[1] = data->influenceBlendWeights.f[4*influence + 1];
|
||||||
else
|
blendWeights[2] = data->influenceBlendWeights.f[4*influence + 2];
|
||||||
blendWeights[numWeights] = (float)data->influenceBlendWeights.b[4*influence + numWeights] / 255.0f;
|
blendWeights[3] = data->influenceBlendWeights.f[4*influence + 3];
|
||||||
|
} else {
|
||||||
if ( blendWeights[numWeights] <= 0.0f )
|
blendWeights[0] = (float)data->influenceBlendWeights.b[4*influence + 0] / 255.0f;
|
||||||
break;
|
blendWeights[1] = (float)data->influenceBlendWeights.b[4*influence + 1] / 255.0f;
|
||||||
|
blendWeights[2] = (float)data->influenceBlendWeights.b[4*influence + 2] / 255.0f;
|
||||||
|
blendWeights[3] = (float)data->influenceBlendWeights.b[4*influence + 3] / 255.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( numWeights == 0 ) {
|
if ( blendWeights[0] <= 0.0f ) {
|
||||||
// no blend joint, use identity matrix.
|
// no blend joint, use identity matrix.
|
||||||
vtxMat[0] = identityMatrix[0];
|
vtxMat[0] = identityMatrix[0];
|
||||||
vtxMat[1] = identityMatrix[1];
|
vtxMat[1] = identityMatrix[1];
|
||||||
|
@ -1470,7 +1527,11 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) {
|
||||||
vtxMat[10] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10];
|
vtxMat[10] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 10];
|
||||||
vtxMat[11] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11];
|
vtxMat[11] = blendWeights[0] * poseMats[12 * data->influenceBlendIndexes[4*influence + 0] + 11];
|
||||||
|
|
||||||
for( j = 1; j < numWeights; j++ ) {
|
for( j = 1; j < 3; j++ ) {
|
||||||
|
if ( blendWeights[j] <= 0.0f ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
vtxMat[0] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 0];
|
vtxMat[0] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 0];
|
||||||
vtxMat[1] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 1];
|
vtxMat[1] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 1];
|
||||||
vtxMat[2] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 2];
|
vtxMat[2] += blendWeights[j] * poseMats[12 * data->influenceBlendIndexes[4*influence + j] + 2];
|
||||||
|
|
|
@ -3086,6 +3086,7 @@ static void UI_Update(const char *name) {
|
||||||
trap_Cvar_SetValue( "r_stencilbits", 8 );
|
trap_Cvar_SetValue( "r_stencilbits", 8 );
|
||||||
trap_Cvar_SetValue( "r_picmip", 0 );
|
trap_Cvar_SetValue( "r_picmip", 0 );
|
||||||
trap_Cvar_SetValue( "r_mode", 4 );
|
trap_Cvar_SetValue( "r_mode", 4 );
|
||||||
|
trap_Cvar_Set( "ui_videomode", "800x600" );
|
||||||
trap_Cvar_SetValue( "r_texturebits", 32 );
|
trap_Cvar_SetValue( "r_texturebits", 32 );
|
||||||
trap_Cvar_SetValue( "r_fastSky", 0 );
|
trap_Cvar_SetValue( "r_fastSky", 0 );
|
||||||
trap_Cvar_SetValue( "r_inGameVideo", 1 );
|
trap_Cvar_SetValue( "r_inGameVideo", 1 );
|
||||||
|
@ -3103,6 +3104,7 @@ static void UI_Update(const char *name) {
|
||||||
trap_Cvar_Reset( "r_stencilbits" );
|
trap_Cvar_Reset( "r_stencilbits" );
|
||||||
trap_Cvar_SetValue( "r_picmip", 1 );
|
trap_Cvar_SetValue( "r_picmip", 1 );
|
||||||
trap_Cvar_SetValue( "r_mode", 3 );
|
trap_Cvar_SetValue( "r_mode", 3 );
|
||||||
|
trap_Cvar_Set( "ui_videomode", "640x480" );
|
||||||
trap_Cvar_SetValue( "r_texturebits", 0 );
|
trap_Cvar_SetValue( "r_texturebits", 0 );
|
||||||
trap_Cvar_SetValue( "r_fastSky", 0 );
|
trap_Cvar_SetValue( "r_fastSky", 0 );
|
||||||
trap_Cvar_SetValue( "r_inGameVideo", 1 );
|
trap_Cvar_SetValue( "r_inGameVideo", 1 );
|
||||||
|
@ -3120,6 +3122,7 @@ static void UI_Update(const char *name) {
|
||||||
trap_Cvar_Reset( "r_stencilbits" );
|
trap_Cvar_Reset( "r_stencilbits" );
|
||||||
trap_Cvar_SetValue( "r_picmip", 1 );
|
trap_Cvar_SetValue( "r_picmip", 1 );
|
||||||
trap_Cvar_SetValue( "r_mode", 3 );
|
trap_Cvar_SetValue( "r_mode", 3 );
|
||||||
|
trap_Cvar_Set( "ui_videomode", "640x480" );
|
||||||
trap_Cvar_SetValue( "r_texturebits", 0 );
|
trap_Cvar_SetValue( "r_texturebits", 0 );
|
||||||
trap_Cvar_SetValue( "cg_shadows", 0 );
|
trap_Cvar_SetValue( "cg_shadows", 0 );
|
||||||
trap_Cvar_SetValue( "r_fastSky", 1 );
|
trap_Cvar_SetValue( "r_fastSky", 1 );
|
||||||
|
@ -3136,6 +3139,7 @@ static void UI_Update(const char *name) {
|
||||||
trap_Cvar_SetValue( "r_depthbits", 16 );
|
trap_Cvar_SetValue( "r_depthbits", 16 );
|
||||||
trap_Cvar_SetValue( "r_stencilbits", 0 );
|
trap_Cvar_SetValue( "r_stencilbits", 0 );
|
||||||
trap_Cvar_SetValue( "r_mode", 3 );
|
trap_Cvar_SetValue( "r_mode", 3 );
|
||||||
|
trap_Cvar_Set( "ui_videomode", "640x480" );
|
||||||
trap_Cvar_SetValue( "r_picmip", 2 );
|
trap_Cvar_SetValue( "r_picmip", 2 );
|
||||||
trap_Cvar_SetValue( "r_texturebits", 16 );
|
trap_Cvar_SetValue( "r_texturebits", 16 );
|
||||||
trap_Cvar_SetValue( "cg_shadows", 0 );
|
trap_Cvar_SetValue( "cg_shadows", 0 );
|
||||||
|
@ -5079,6 +5083,8 @@ void _UI_Init( qboolean inGameLoad ) {
|
||||||
// cache redundant calulations
|
// cache redundant calulations
|
||||||
trap_GetGlconfig( &uiInfo.uiDC.glconfig );
|
trap_GetGlconfig( &uiInfo.uiDC.glconfig );
|
||||||
|
|
||||||
|
trap_Cvar_Set("ui_videomode", va( "%dx%d", uiInfo.uiDC.glconfig.vidWidth, uiInfo.uiDC.glconfig.vidHeight ) );
|
||||||
|
|
||||||
// for 640x480 virtualized screen
|
// for 640x480 virtualized screen
|
||||||
uiInfo.uiDC.yscale = uiInfo.uiDC.glconfig.vidHeight * (1.0/480.0);
|
uiInfo.uiDC.yscale = uiInfo.uiDC.glconfig.vidHeight * (1.0/480.0);
|
||||||
uiInfo.uiDC.xscale = uiInfo.uiDC.glconfig.vidWidth * (1.0/640.0);
|
uiInfo.uiDC.xscale = uiInfo.uiDC.glconfig.vidWidth * (1.0/640.0);
|
||||||
|
@ -5871,6 +5877,7 @@ static cvarTable_t cvarTable[] = {
|
||||||
{ &ui_realCaptureLimit, "capturelimit", "8", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART},
|
{ &ui_realCaptureLimit, "capturelimit", "8", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART},
|
||||||
{ &ui_serverStatusTimeOut, "ui_serverStatusTimeOut", "7000", CVAR_ARCHIVE},
|
{ &ui_serverStatusTimeOut, "ui_serverStatusTimeOut", "7000", CVAR_ARCHIVE},
|
||||||
|
|
||||||
|
{ NULL, "ui_videomode", "", CVAR_ROM },
|
||||||
{ NULL, "g_localTeamPref", "", 0 },
|
{ NULL, "g_localTeamPref", "", 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2055,6 +2055,26 @@ qboolean Item_Multi_HandleKey(itemDef_t *item, int key) {
|
||||||
} else if ( current >= max ) {
|
} else if ( current >= max ) {
|
||||||
current = 0;
|
current = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (multiPtr->videoMode) {
|
||||||
|
if (multiPtr->cvarValue[current] != -1) {
|
||||||
|
DC->setCVar("r_mode", va("%i", (int) multiPtr->cvarValue[current] ));
|
||||||
|
} else {
|
||||||
|
int w, h;
|
||||||
|
char *x;
|
||||||
|
char str[8];
|
||||||
|
|
||||||
|
x = strchr( multiPtr->cvarStr[current], 'x' ) + 1;
|
||||||
|
Q_strncpyz( str, multiPtr->cvarStr[current], MIN( x-multiPtr->cvarStr[current], sizeof( str ) ) );
|
||||||
|
w = atoi( str );
|
||||||
|
h = atoi( x );
|
||||||
|
|
||||||
|
DC->setCVar("r_mode", "-1");
|
||||||
|
DC->setCVar("r_customwidth", va("%i", w));
|
||||||
|
DC->setCVar("r_customheight", va("%i", h));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (multiPtr->strDef) {
|
if (multiPtr->strDef) {
|
||||||
DC->setCVar(item->cvar, multiPtr->cvarStr[current]);
|
DC->setCVar(item->cvar, multiPtr->cvarStr[current]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -5003,6 +5023,7 @@ qboolean ItemParse_cvarStrList( itemDef_t *item, int handle ) {
|
||||||
multiPtr = (multiDef_t*)item->typeData;
|
multiPtr = (multiDef_t*)item->typeData;
|
||||||
multiPtr->count = 0;
|
multiPtr->count = 0;
|
||||||
multiPtr->strDef = qtrue;
|
multiPtr->strDef = qtrue;
|
||||||
|
multiPtr->videoMode = qfalse;
|
||||||
|
|
||||||
if (!trap_PC_ReadToken(handle, &token))
|
if (!trap_PC_ReadToken(handle, &token))
|
||||||
return qfalse;
|
return qfalse;
|
||||||
|
@ -5051,6 +5072,7 @@ qboolean ItemParse_cvarFloatList( itemDef_t *item, int handle ) {
|
||||||
multiPtr = (multiDef_t*)item->typeData;
|
multiPtr = (multiDef_t*)item->typeData;
|
||||||
multiPtr->count = 0;
|
multiPtr->count = 0;
|
||||||
multiPtr->strDef = qfalse;
|
multiPtr->strDef = qfalse;
|
||||||
|
multiPtr->videoMode = qfalse;
|
||||||
|
|
||||||
if (!trap_PC_ReadToken(handle, &token))
|
if (!trap_PC_ReadToken(handle, &token))
|
||||||
return qfalse;
|
return qfalse;
|
||||||
|
@ -5227,6 +5249,61 @@ void Item_SetupKeywordHash(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *builtinResolutions[ ] =
|
||||||
|
{
|
||||||
|
"320x240",
|
||||||
|
"400x300",
|
||||||
|
"512x384",
|
||||||
|
"640x480",
|
||||||
|
"800x600",
|
||||||
|
"960x720",
|
||||||
|
"1024x768",
|
||||||
|
"1152x864",
|
||||||
|
"1280x1024",
|
||||||
|
"1600x1200",
|
||||||
|
"2048x1536",
|
||||||
|
"856x480",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *knownRatios[ ][2] =
|
||||||
|
{
|
||||||
|
{ "1.25:1", "5:4" },
|
||||||
|
{ "1.33:1", "4:3" },
|
||||||
|
{ "1.50:1", "3:2" },
|
||||||
|
{ "1.56:1", "14:9" },
|
||||||
|
{ "1.60:1", "16:10" },
|
||||||
|
{ "1.67:1", "5:3" },
|
||||||
|
{ "1.78:1", "16:9" },
|
||||||
|
{ NULL , NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
UI_ResolutionToAspect
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
static void UI_ResolutionToAspect( const char *resolution, char *aspect, size_t aspectLength ) {
|
||||||
|
int i, w, h;
|
||||||
|
char *x;
|
||||||
|
char str[8];
|
||||||
|
|
||||||
|
// calculate resolution's aspect ratio
|
||||||
|
x = strchr( resolution, 'x' ) + 1;
|
||||||
|
Q_strncpyz( str, resolution, MIN( x-resolution, sizeof( str ) ) );
|
||||||
|
w = atoi( str );
|
||||||
|
h = atoi( x );
|
||||||
|
Com_sprintf( aspect, aspectLength, "%.2f:1", (float)w / (float)h );
|
||||||
|
|
||||||
|
// rename common ratios ("1.33:1" -> "4:3")
|
||||||
|
for( i = 0; knownRatios[i][0]; i++ ) {
|
||||||
|
if( !Q_stricmp( aspect, knownRatios[i][0] ) ) {
|
||||||
|
Q_strncpyz( aspect, knownRatios[i][1], aspectLength );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============
|
===============
|
||||||
Item_ApplyHacks
|
Item_ApplyHacks
|
||||||
|
@ -5261,6 +5338,89 @@ static void Item_ApplyHacks( itemDef_t *item ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replace mode list and use a temporary ui_videomode cvar for handling custom modes
|
||||||
|
if ( item->type == ITEM_TYPE_MULTI && item->cvar && !Q_stricmp( item->cvar, "r_mode" ) ) {
|
||||||
|
multiDef_t *multiPtr = (multiDef_t*)item->typeData;
|
||||||
|
int i, oldCount;
|
||||||
|
char resbuf[MAX_STRING_CHARS];
|
||||||
|
char modeName[32], aspect[8];
|
||||||
|
|
||||||
|
item->cvar = "ui_videomode";
|
||||||
|
multiPtr->strDef = qtrue;
|
||||||
|
multiPtr->videoMode = qtrue;
|
||||||
|
|
||||||
|
oldCount = multiPtr->count;
|
||||||
|
multiPtr->count = 0;
|
||||||
|
|
||||||
|
DC->getCVarString( "r_availableModes", resbuf, sizeof( resbuf ) );
|
||||||
|
|
||||||
|
if ( *resbuf ) {
|
||||||
|
char *s = resbuf, *mode;
|
||||||
|
|
||||||
|
while ( s && multiPtr->count < MAX_MULTI_CVARS ) {
|
||||||
|
mode = s;
|
||||||
|
|
||||||
|
s = strchr(s, ' ');
|
||||||
|
if( s )
|
||||||
|
*s++ = '\0';
|
||||||
|
|
||||||
|
UI_ResolutionToAspect( mode, aspect, sizeof( aspect ) );
|
||||||
|
Com_sprintf( modeName, sizeof( modeName ), "%s (%s)", mode, aspect );
|
||||||
|
|
||||||
|
multiPtr->cvarList[multiPtr->count] = String_Alloc( modeName );
|
||||||
|
|
||||||
|
for ( i = 0; builtinResolutions[i]; i++ ) {
|
||||||
|
if( !Q_stricmp( builtinResolutions[i], mode ) ) {
|
||||||
|
multiPtr->cvarStr[multiPtr->count] = builtinResolutions[i];
|
||||||
|
multiPtr->cvarValue[multiPtr->count] = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( builtinResolutions[i] == NULL ) {
|
||||||
|
multiPtr->cvarStr[multiPtr->count] = String_Alloc( mode );
|
||||||
|
multiPtr->cvarValue[multiPtr->count] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiPtr->count++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for ( i = 0; builtinResolutions[i] && multiPtr->count < MAX_MULTI_CVARS; i++ ) {
|
||||||
|
UI_ResolutionToAspect( builtinResolutions[i], aspect, sizeof( aspect ) );
|
||||||
|
Com_sprintf( modeName, sizeof( modeName ), "%s (%s)", builtinResolutions[i], aspect );
|
||||||
|
|
||||||
|
multiPtr->cvarList[multiPtr->count] = String_Alloc( modeName );
|
||||||
|
multiPtr->cvarStr[multiPtr->count] = builtinResolutions[i];
|
||||||
|
multiPtr->cvarValue[multiPtr->count] = i;
|
||||||
|
multiPtr->count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add custom resolution if not in mode list
|
||||||
|
if ( multiPtr->count < MAX_MULTI_CVARS ) {
|
||||||
|
char currentResolution[20];
|
||||||
|
|
||||||
|
Com_sprintf( currentResolution, sizeof ( currentResolution ), "%dx%d", DC->glconfig.vidWidth, DC->glconfig.vidHeight );
|
||||||
|
for ( i = 0; i < multiPtr->count; i++ ) {
|
||||||
|
if ( !Q_stricmp( multiPtr->cvarStr[i], currentResolution ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( i == multiPtr->count ) {
|
||||||
|
UI_ResolutionToAspect( currentResolution, aspect, sizeof( aspect ) );
|
||||||
|
Com_sprintf( modeName, sizeof( modeName ), "%s (%s)", currentResolution, aspect );
|
||||||
|
|
||||||
|
multiPtr->cvarList[multiPtr->count] = String_Alloc( modeName );
|
||||||
|
multiPtr->cvarStr[multiPtr->count] = String_Alloc( currentResolution );
|
||||||
|
multiPtr->cvarValue[multiPtr->count] = -1;
|
||||||
|
multiPtr->count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Com_Printf( "Found video mode list with %d modes, replaced list with %d modes\n", oldCount, multiPtr->count );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -203,6 +203,7 @@ typedef struct multiDef_s {
|
||||||
float cvarValue[MAX_MULTI_CVARS];
|
float cvarValue[MAX_MULTI_CVARS];
|
||||||
int count;
|
int count;
|
||||||
qboolean strDef;
|
qboolean strDef;
|
||||||
|
qboolean videoMode;
|
||||||
} multiDef_t;
|
} multiDef_t;
|
||||||
|
|
||||||
typedef struct modelDef_s {
|
typedef struct modelDef_s {
|
||||||
|
|
338
misc/msvc12/.gitignore
vendored
Normal file
338
misc/msvc12/.gitignore
vendored
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUNIT
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# JustCode is a .NET coding add-in
|
||||||
|
.JustCode
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
# ASP.NET Core default setup: bower directory is configured as wwwroot/lib/ and bower restore is true
|
||||||
|
**/wwwroot/lib/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# JetBrains Rider
|
||||||
|
.idea/
|
||||||
|
*.sln.iml
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
|
@ -184,6 +184,11 @@ Cvars for advanced material usage:
|
||||||
1 - Use parallax occlusion mapping.
|
1 - Use parallax occlusion mapping.
|
||||||
2 - Use relief mapping. (slower)
|
2 - Use relief mapping. (slower)
|
||||||
|
|
||||||
|
* `r_parallaxMapShadows` - Enable self-shadowing on parallax map
|
||||||
|
supported materials.
|
||||||
|
0 - No. (default)
|
||||||
|
1 - Yes.
|
||||||
|
|
||||||
* `r_baseSpecular` - Set the specular reflectance of materials
|
* `r_baseSpecular` - Set the specular reflectance of materials
|
||||||
which don't include a specular map or
|
which don't include a specular map or
|
||||||
use the specularReflectance keyword.
|
use the specularReflectance keyword.
|
||||||
|
|
Loading…
Reference in a new issue