214 lines
5.0 KiB
C
214 lines
5.0 KiB
C
|
|
||
|
#include "bsplib.h"
|
||
|
#include "byteorder.h"
|
||
|
|
||
|
//==========================================================================
|
||
|
int FindMiptex( const char *name )
|
||
|
{
|
||
|
rgbdata_t *image;
|
||
|
int i;
|
||
|
|
||
|
if(!com.strlen( name )) return 0;
|
||
|
|
||
|
for( i = 0; i < numshaders; i++ )
|
||
|
{
|
||
|
if( !com.stricmp( dshaders[i].name, name ))
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
// allocate a new texture
|
||
|
if( numshaders == MAX_MAP_SHADERS )
|
||
|
Sys_Break( "MAX_MAP_SHADERS limit exceeded\n" );
|
||
|
|
||
|
// alloc new texture
|
||
|
com.strncpy( dshaders[i].name, name, sizeof( dshaders[i].name ));
|
||
|
|
||
|
image = FS_LoadImage( name, NULL, 0 );
|
||
|
if( image )
|
||
|
{
|
||
|
// save texture dimensions that can be used
|
||
|
// for replacing original textures with HQ images
|
||
|
dshaders[i].size[0] = image->width;
|
||
|
dshaders[i].size[1] = image->height;
|
||
|
FS_FreeImage( image );
|
||
|
}
|
||
|
else dshaders[i].size[0] = dshaders[i].size[1] = -1; // technically an error
|
||
|
|
||
|
return numshaders++;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
==================
|
||
|
textureAxisFromPlane
|
||
|
==================
|
||
|
*/
|
||
|
vec3_t baseaxis[18] =
|
||
|
{
|
||
|
{0,0,1}, {1,0,0}, {0,-1,0}, // floor
|
||
|
{0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling
|
||
|
{1,0,0}, {0,1,0}, {0,0,-1}, // west wall
|
||
|
{-1,0,0}, {0,1,0}, {0,0,-1}, // east wall
|
||
|
{0,1,0}, {1,0,0}, {0,0,-1}, // south wall
|
||
|
{0,-1,0}, {1,0,0}, {0,0,-1}, // north wall
|
||
|
};
|
||
|
|
||
|
void TextureAxisFromPlane( plane_t *plane, vec3_t xv, vec3_t yv )
|
||
|
{
|
||
|
int bestaxis = 0;
|
||
|
vec_t dot, best = 0;
|
||
|
int i;
|
||
|
|
||
|
for( i = 0; i < 6; i++ )
|
||
|
{
|
||
|
dot = DotProduct( plane->normal, baseaxis[i*3] );
|
||
|
if (dot > best)
|
||
|
{
|
||
|
best = dot;
|
||
|
bestaxis = i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
VectorCopy( baseaxis[bestaxis*3+1], xv );
|
||
|
VectorCopy( baseaxis[bestaxis*3+2], yv );
|
||
|
}
|
||
|
|
||
|
int TexinfoForBrushTexture( plane_t *plane, brush_texture_t *bt, vec3_t origin )
|
||
|
{
|
||
|
vec_t ang, sinv, cosv;
|
||
|
vec3_t vecs[2];
|
||
|
int i, j, k;
|
||
|
dtexinfo_t tx, *tc;
|
||
|
int sv, tv;
|
||
|
vec_t ns, nt;
|
||
|
|
||
|
if( !bt->name[0] ) return 0;
|
||
|
|
||
|
Mem_Set( &tx, 0, sizeof( tx ));
|
||
|
tx.shadernum = FindMiptex( bt->name );
|
||
|
|
||
|
if( bt->brush_type == BRUSH_QUARK )
|
||
|
{
|
||
|
Mem_Copy( tx.vecs, bt->vects.quark.vecs, sizeof( tx.vecs ));
|
||
|
|
||
|
if(!VectorIsNull( origin ))
|
||
|
{
|
||
|
tx.vecs[0][3] += DotProduct( origin, tx.vecs[0] );
|
||
|
tx.vecs[1][3] += DotProduct( origin, tx.vecs[1] );
|
||
|
}
|
||
|
|
||
|
dshaders[tx.shadernum].contentFlags = bt->contents;
|
||
|
dshaders[tx.shadernum].surfaceFlags = bt->flags;
|
||
|
tx.value = bt->value;
|
||
|
}
|
||
|
else if( bt->brush_type != BRUSH_RADIANT )
|
||
|
{
|
||
|
if( bt->brush_type == BRUSH_WORLDCRAFT_21 )
|
||
|
TextureAxisFromPlane( plane, vecs[0], vecs[1] );
|
||
|
if( !bt->vects.hammer.scale[0] ) bt->vects.hammer.scale[0] = 1.0f;
|
||
|
if( !bt->vects.hammer.scale[1] ) bt->vects.hammer.scale[1] = 1.0f;
|
||
|
|
||
|
if( bt->brush_type == BRUSH_WORLDCRAFT_21 )
|
||
|
{
|
||
|
// rotate axis
|
||
|
if( bt->vects.hammer.rotate == 0 )
|
||
|
{
|
||
|
sinv = 0;
|
||
|
cosv = 1;
|
||
|
}
|
||
|
else if( bt->vects.hammer.rotate == 90 )
|
||
|
{
|
||
|
sinv = 1;
|
||
|
cosv = 0;
|
||
|
}
|
||
|
else if( bt->vects.hammer.rotate == 180 )
|
||
|
{
|
||
|
sinv = 0;
|
||
|
cosv = -1;
|
||
|
}
|
||
|
else if( bt->vects.hammer.rotate == 270 )
|
||
|
{
|
||
|
sinv = -1;
|
||
|
cosv = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ang = bt->vects.hammer.rotate / 180 * M_PI;
|
||
|
sinv = com.sin( ang );
|
||
|
cosv = com.cos( ang );
|
||
|
}
|
||
|
if( vecs[0][0] ) sv = 0;
|
||
|
else if( vecs[0][1] ) sv = 1;
|
||
|
else sv = 2;
|
||
|
|
||
|
if( vecs[1][0] ) tv = 0;
|
||
|
else if( vecs[1][1] ) tv = 1;
|
||
|
else tv = 2;
|
||
|
|
||
|
for( i = 0; i < 2; i++ )
|
||
|
{
|
||
|
ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
|
||
|
nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
|
||
|
vecs[i][sv] = ns;
|
||
|
vecs[i][tv] = nt;
|
||
|
}
|
||
|
|
||
|
for( i = 0; i < 2; i++ )
|
||
|
for( j = 0; j < 3; j++ )
|
||
|
tx.vecs[i][j] = vecs[i][j] / bt->vects.hammer.scale[i];
|
||
|
}
|
||
|
else if( bt->brush_type == BRUSH_WORLDCRAFT_22 )
|
||
|
{
|
||
|
vec_t scale;
|
||
|
|
||
|
scale = 1 / bt->vects.hammer.scale[0];
|
||
|
VectorScale( bt->vects.hammer.UAxis, scale, tx.vecs[0] );
|
||
|
scale = 1 / bt->vects.hammer.scale[1];
|
||
|
VectorScale( bt->vects.hammer.VAxis, scale, tx.vecs[1] );
|
||
|
}
|
||
|
|
||
|
tx.vecs[0][3] = bt->vects.hammer.shift[0] + DotProduct( origin, tx.vecs[0] );
|
||
|
tx.vecs[1][3] = bt->vects.hammer.shift[1] + DotProduct( origin, tx.vecs[1] );
|
||
|
}
|
||
|
else if( bt->brush_type == BRUSH_RADIANT )
|
||
|
{
|
||
|
VectorCopy( bt->vects.radiant.matrix[0], tx.vecs[0] );
|
||
|
VectorCopy( bt->vects.radiant.matrix[1], tx.vecs[1] );
|
||
|
|
||
|
if(!VectorIsNull( origin ))
|
||
|
{
|
||
|
tx.vecs[0][3] += DotProduct( origin, tx.vecs[0] );
|
||
|
tx.vecs[1][3] += DotProduct( origin, tx.vecs[1] );
|
||
|
}
|
||
|
|
||
|
dshaders[tx.shadernum].contentFlags = bt->contents;
|
||
|
dshaders[tx.shadernum].surfaceFlags = bt->flags;
|
||
|
tx.value = bt->value;
|
||
|
}
|
||
|
|
||
|
dshaders[tx.shadernum].contentFlags = bt->contents;
|
||
|
dshaders[tx.shadernum].surfaceFlags = bt->flags;
|
||
|
tx.value = bt->value;
|
||
|
|
||
|
// find the texinfo
|
||
|
tc = texinfo;
|
||
|
for( i = 0; i < numtexinfo; i++, tc++ )
|
||
|
{
|
||
|
if( tc->value != tx.value ) continue;
|
||
|
for( j = 0; j < 2; j++ )
|
||
|
{
|
||
|
if( tc->shadernum != tx.shadernum )
|
||
|
goto skip;
|
||
|
for( k = 0; k < 4; k++ )
|
||
|
{
|
||
|
if( tc->vecs[j][k] != tx.vecs[j][k] )
|
||
|
goto skip;
|
||
|
}
|
||
|
}
|
||
|
return i;
|
||
|
skip:;
|
||
|
}
|
||
|
|
||
|
// register new texinfo
|
||
|
*tc = tx;
|
||
|
return numtexinfo++;
|
||
|
}
|