14 Jul 2009

This commit is contained in:
g-cont 2009-07-14 00:00:00 +04:00 committed by Alibek Omarov
parent d0898a0cd5
commit 6716e6a52d
12 changed files with 667 additions and 161 deletions

View File

@ -1,16 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: engine - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
engine.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -12,6 +12,9 @@
#define COLLISION_SNAP (1.0f / COLLISION_SNAPSCALE)
#define COLLISION_SNAP2 (2.0f / COLLISION_SNAPSCALE)
#define COLLISION_PLANE_DIST_EPSILON (2.0f / COLLISION_SNAPSCALE)
#define SIDE_INVALID -1
#define SIDE_X 0
#define SIDE_Y 1
cvar_t *cm_impactnudge;
cvar_t *cm_startnudge;
@ -60,6 +63,9 @@ void CM_CollisionValidateBrush( cbrushf_t *brush )
int j, k, pointsoffplanes, pointonplanes, pointswithinsufficientplanes, printbrush;
float d;
if( ph.developer < D_ERROR )
return;
printbrush = false;
if( !brush->numpoints )
{
@ -139,6 +145,280 @@ float furthestplanedist_float( const float *normal, const cpointf_t *points, int
return bestdist;
}
static int CM_PatchTesselation( float largestsquared3xcurvearea, float tolerance )
{
float f;
// f is actually a squared 2x curve area... so the formula had to be adjusted to give roughly the same subdivisions
f = pow( largestsquared3xcurvearea / 64.0f, 0.25f ) / tolerance;
if( f < 0.0001f ) // TOTALLY flat patches
return 0;
else if( f < 2.0f )
return 1;
return (int)floor(log( f ) / log( 2 )) + 1;
}
static float CM_Squared3xCurveArea(const float *a, const float *control, const float *b, int components)
{
int c;
float aa = 0, bb = 0, ab = 0;
for( c = 0; c < components; c++ )
{
float xa = a[c] - control[c];
float xb = b[c] - control[c];
aa += xa * xa;
ab += xa * xb;
bb += xb * xb;
}
return aa * bb - ab * ab;
}
// returns how much tesselation of each segment is needed to remain under tolerance
int CM_PatchTesselationOnX( int patchwidth, int patchheight, int components, const float *in, float tolerance )
{
int x, y;
const float *patch;
float squared3xcurvearea, largestsquared3xcurvearea = 0;
for( y = 0; y < patchheight; y++ )
{
for( x = 0; x < patchwidth - 1; x += 2 )
{
patch = in + ((y * patchwidth) + x) * components;
squared3xcurvearea = CM_Squared3xCurveArea( &patch[0], &patch[components], &patch[2*components], components );
if( largestsquared3xcurvearea < squared3xcurvearea )
largestsquared3xcurvearea = squared3xcurvearea;
}
}
return CM_PatchTesselation( largestsquared3xcurvearea, tolerance );
}
// returns how much tesselation of each segment is needed to remain under tolerance
int CM_PatchTesselationOnY( int patchwidth, int patchheight, int components, const float *in, float tolerance )
{
int x, y;
const float *patch;
float squared3xcurvearea, largestsquared3xcurvearea = 0;
for( y = 0; y < patchheight - 1; y += 2 )
{
for( x = 0; x < patchwidth; x++ )
{
patch = in + ((y * patchwidth) + x) * components;
squared3xcurvearea = CM_Squared3xCurveArea( &patch[0], &patch[patchwidth*components], &patch[2*patchwidth*components], components );
if( largestsquared3xcurvearea < squared3xcurvearea )
largestsquared3xcurvearea = squared3xcurvearea;
}
}
return CM_PatchTesselation( largestsquared3xcurvearea, tolerance );
}
int CM_PatchDimForTess( int size, int tess )
{
if( tess > 0 )
return (size - 1) * tess + 1;
else if( tess == 0 )
return (size - 1) / 2 + 1;
return 0; // Maybe warn about wrong tess here?
}
void CM_PatchTesselateFloat( int numcomponents, int outputstride, float *outputvertices, int patchwidth, int patchheight, int inputstride, float *patchvertices, int tesselationwidth, int tesselationheight )
{
int k, l, x, y, component, outputwidth = CM_PatchDimForTess( patchwidth, tesselationwidth );
float px, py, *v, a, b, c, *cp[3][3], temp[3][64];
int xmax = max( 1, 2 * tesselationwidth );
int ymax = max( 1, 2 * tesselationheight );
// iterate over the individual 3x3 quadratic spline surfaces one at a time
// expanding them to fill the output array (with some overlap to ensure
// the edges are filled)
for( k = 0; k < patchheight - 1; k += 2 )
{
for( l = 0; l < patchwidth - 1; l += 2 )
{
// set up control point pointers for quicker lookup later
for( y = 0; y < 3; y++ )
for( x = 0; x < 3; x++ )
cp[y][x] = (float *)((byte *)patchvertices + ((k+y) * patchwidth + (l+x)) * inputstride );
// for each row...
for( y = 0; y <= ymax; y++ )
{
// calculate control points for this row by collapsing the 3
// rows of control points to one row using py
py = (float)y / (float)ymax;
// calculate quadratic spline weights for py
a = ((1.0f - py) * (1.0f - py));
b = ((1.0f - py) * (2.0f * py));
c = (( py) * ( py));
for( component = 0; component < numcomponents; component++ )
{
temp[0][component] = cp[0][0][component] * a + cp[1][0][component] * b + cp[2][0][component] * c;
temp[1][component] = cp[0][1][component] * a + cp[1][1][component] * b + cp[2][1][component] * c;
temp[2][component] = cp[0][2][component] * a + cp[1][2][component] * b + cp[2][2][component] * c;
}
// fetch a pointer to the beginning of the output vertex row
v = (float *)((byte *)outputvertices + ((k * ymax / 2 + y) * outputwidth + l * xmax / 2) * outputstride);
// for each column of the row...
for( x = 0; x <= xmax; x++ )
{
// calculate point based on the row control points
px = (float)x / (float)xmax;
// calculate quadratic spline weights for px
// (could be precalculated)
a = ((1.0f - px) * (1.0f - px));
b = ((1.0f - px) * (2.0f * px));
c = (( px) * ( px));
for( component = 0; component < numcomponents; component++ )
v[component] = temp[0][component] * a + temp[1][component] * b + temp[2][component] * c;
// advance to next output vertex using outputstride
// (the next vertex may not be directly following this
// one, as this may be part of a larger structure)
v = (float *)((byte *)v + outputstride);
}
}
}
}
}
// find an equal vertex in array. check only vertices with odd X and Y
static int CM_FindEqualOddVertexInArray( int numcomponents, float *vertex, float *vertices, int width, int height )
{
int x, y, j;
for( y = 0; y < height; y += 2 )
{
for( x = 0; x < width; x += 2 )
{
bool found = true;
for( j = 0; j < numcomponents; j++ )
{
if( fabs(*( vertex + j ) - *(vertices + j)) > 0.05f )
{
found = false;
break;
}
}
if( found ) return y * width + x;
vertices += numcomponents * 2;
}
vertices += numcomponents * (width - 1);
}
return -1;
}
static int CM_GetSide( int p1, int p2, int width, int height, int *pointdist )
{
int x1 = p1 % width, y1 = p1 / width;
int x2 = p2 % width, y2 = p2 / width;
if( p1 < 0 || p2 < 0 )
return SIDE_INVALID;
if( x1 == x2 )
{
if( y1 != y2 )
{
*pointdist = abs( y2 - y1 );
return SIDE_Y;
}
else return SIDE_INVALID;
}
else if( y1 == y2 )
{
*pointdist = abs( x2 - x1 );
return SIDE_X;
}
return SIDE_INVALID;
}
// increase tesselation of one of two touching patches to make a seamless connection between them
// returns 0 in case if patches were not modified, otherwise 1
int CM_PatchAdjustTesselation( int numcomponents, patchinfo_t *patch1, float *patchvertices1, patchinfo_t *patch2, float *patchvertices2 )
{
// what we are doing here is:
// we take for each corner of one patch
// and check if the other patch contains that corner
// once we have a pair of such matches
struct { int id1, id2; } commonverts[8];
int i, j, k, side1, side2, *tess1, *tess2;
int dist1, dist2;
bool modified = false;
// potential paired vertices (corners of the first patch)
commonverts[0].id1 = 0;
commonverts[1].id1 = patch1->xsize-1;
commonverts[2].id1 = patch1->xsize*(patch1->ysize-1);
commonverts[3].id1 = patch1->xsize*patch1->ysize-1;
for( i = 0; i < 4; ++i )
commonverts[i].id2 = CM_FindEqualOddVertexInArray( numcomponents, patchvertices1 + numcomponents * commonverts[i].id1, patchvertices2, patch2->xsize, patch2->ysize );
// corners of the second patch
commonverts[4].id2 = 0;
commonverts[5].id2 = patch2->xsize-1;
commonverts[6].id2 = patch2->xsize*(patch2->ysize-1);
commonverts[7].id2 = patch2->xsize*patch2->ysize-1;
for( i = 4; i < 8; ++i )
commonverts[i].id1 = CM_FindEqualOddVertexInArray( numcomponents, patchvertices2 + numcomponents * commonverts[i].id2, patchvertices1, patch1->xsize, patch1->ysize );
for( i = 0; i < 8; ++i )
{
for( j = i+1; j < 8; ++j )
{
side1 = CM_GetSide( commonverts[i].id1, commonverts[j].id1, patch1->xsize, patch1->ysize, &dist1 );
side2 = CM_GetSide( commonverts[i].id2, commonverts[j].id2, patch2->xsize, patch2->ysize, &dist2 );
if( side1 == SIDE_INVALID || side2 == SIDE_INVALID )
continue;
if( dist1 != dist2 )
{
// no patch welding if the resolutions mismatch
continue;
}
// update every lod level
for( k = 0; k < PATCH_LODS_NUM; ++k )
{
tess1 = side1 == SIDE_X ? &patch1->lods[k].xtess : &patch1->lods[k].ytess;
tess2 = side2 == SIDE_X ? &patch2->lods[k].xtess : &patch2->lods[k].ytess;
if( *tess1 != *tess2 )
{
if( *tess1 < *tess2 )
*tess1 = *tess2;
else *tess2 = *tess1;
modified = true;
}
}
}
}
return modified;
}
void CM_PatchTriangleElements( int *elements, int width, int height, int firstvertex )
{
int x, y, row0, row1;
for( y = 0; y < height - 1; y++ )
{
row0 = firstvertex + (y + 0) * width;
row1 = firstvertex + (y + 1) * width;
for( x = 0; x < width - 1; x++ )
{
*elements++ = row0;
*elements++ = row1;
*elements++ = row0 + 1;
*elements++ = row1;
*elements++ = row1 + 1;
*elements++ = row0 + 1;
row0++;
row1++;
}
}
}
cbrushf_t *CM_CollisionNewBrushFromPlanes( byte *mempool, int numoriginalplanes, const cplanef_t *originalplanes, int supercontents )
{

View File

@ -15,6 +15,25 @@
#define CAPSULE_MODEL_HANDLE MAX_MODELS - 2
#define BOX_MODEL_HANDLE MAX_MODELS - 1
enum
{
PATCH_LOD_COLLISION = 0,
PATCH_LOD_VISUAL,
PATCH_LODS_NUM
};
typedef struct patchinfo_s
{
int xsize;
int ysize;
struct
{
int xtess;
int ytess;
} lods[PATCH_LODS_NUM];
} patchinfo_t;
typedef struct cpointf_s
{
float v[3];
@ -166,7 +185,7 @@ typedef struct clipmap_s
dleafbrush_t *leafbrushes;
dleafface_t *leafsurfaces;
cnode_t *nodes; // 6 extra planes for box hull
cpointf_t *vertices;
vec3_t *vertices;
csurface_t *surfaces; // source collision data
cbrush_t *brushes;
cbrushside_t *brushsides;
@ -179,10 +198,11 @@ typedef struct clipmap_s
int numbrushsides;
int numleafbrushes;
int numleafsurfaces;
int numtexinfo;
int numtriangles;
int numplanes;
int numnodes;
int numleafs; // allow leaf funcs to be called without a map
int numverts;
int numshaders;
int numbrushes;
int numsurfaces;
@ -327,6 +347,12 @@ cbrushf_t *CM_CollisionBrushForBox( const matrix4x4 matrix, const vec3_t mins, c
void CM_CollisionBoundingBoxOfBrushTraceSegment( const cbrushf_t *start, const cbrushf_t *end, vec3_t mins, vec3_t maxs, float startfrac, float endfrac );
float CM_CollisionClipTrace_LineSphere( double *linestart, double *lineend, double *sphereorigin, double sphereradius, double *impactpoint, double *impactnormal );
void CM_CollisionTraceLineTriangleFloat( trace_t *trace, const vec3_t linestart, const vec3_t lineend, const float *point0, const float *point1, const float *point2, int supercontents, int surfaceflags, csurface_t *texture );
void CM_PatchTesselateFloat( int numcomponents, int outputstride, float *outputvertices, int patchwidth, int patchheight, int inputstride, float *patchvertices, int tesselationwidth, int tesselationheight );
int CM_PatchAdjustTesselation( int numcomponents, patchinfo_t *patch1, float *patchvertices1, patchinfo_t *patch2, float *patchvertices2 );
int CM_PatchTesselationOnX( int patchwidth, int patchheight, int components, const float *in, float tolerance );
int CM_PatchTesselationOnY( int patchwidth, int patchheight, int components, const float *in, float tolerance );
void CM_PatchTriangleElements( int *elements, int width, int height, int firstvertex );
int CM_PatchDimForTess( int size, int tess );
// traces a box move against a single entity
// mins and maxs are relative

View File

@ -7,6 +7,26 @@
#include "matrix_lib.h"
#include "const.h"
#define PATCHTESS_SAME_LODGROUP( a, b ) \
( \
(a).lodgroup[0] == (b).lodgroup[0] && \
(a).lodgroup[1] == (b).lodgroup[1] && \
(a).lodgroup[2] == (b).lodgroup[2] && \
(a).lodgroup[3] == (b).lodgroup[3] && \
(a).lodgroup[4] == (b).lodgroup[4] && \
(a).lodgroup[5] == (b).lodgroup[5] \
)
typedef struct patchtess_s
{
patchinfo_t info;
// Auxiliary data used only by patch loading code in Mod_Q3BSP_LoadFaces
int surface_id;
float lodgroup[6];
float *originalvertex3f;
} patchtess_t;
clipmap_t cm;
clipmap_static_t cms;
studio_t studio;
@ -24,12 +44,12 @@ int registration_sequence = 0;
*/
void CM_GetPoint( int index, vec3_t out )
{
CM_ConvertPositionToMeters( out, cm.vertices[index].v );
CM_ConvertPositionToMeters( out, cm.vertices[index] );
}
void CM_GetPoint2( int index, vec3_t out )
{
CM_ConvertDimensionToMeters( out, cm.vertices[index].v );
CM_ConvertDimensionToMeters( out, cm.vertices[index] );
}
/*
@ -52,6 +72,42 @@ void CM_BoundBrush( cbrush_t *b )
b->bounds[1][2] = sides[5].plane->dist;
}
void CM_SnapVertices( int numcomponents, int numvertices, float *vertices, float snap )
{
int i;
double isnap = 1.0 / snap;
for( i = 0; i < numvertices * numcomponents; i++ )
vertices[i] = floor( vertices[i] * isnap ) * snap;
}
int CM_RemoveDegenerateTriangles( int numtriangles, const int *inelement3i, int *outelement3i, const float *vertex3f )
{
int i, outtriangles;
float edgedir1[3], edgedir2[3], temp[3];
// a degenerate triangle is one with no width (thickness, surface area)
// these are characterized by having all 3 points colinear (along a line)
// or having two points identical
// the simplest check is to calculate the triangle's area
for( i = 0, outtriangles = 0; i < numtriangles; i++, inelement3i += 3 )
{
// calculate first edge
VectorSubtract( vertex3f + inelement3i[1] * 3, vertex3f + inelement3i[0] * 3, edgedir1 );
VectorSubtract( vertex3f + inelement3i[2] * 3, vertex3f + inelement3i[0] * 3, edgedir2 );
CrossProduct( edgedir1, edgedir2, temp );
if( VectorLength2( temp ) < 0.001f )
continue; // degenerate triangle (no area)
// valid triangle (has area)
VectorCopy( inelement3i, outelement3i );
outelement3i += 3;
outtriangles++;
}
return outtriangles;
}
/*
================
CM_FreeModel
@ -306,6 +362,7 @@ void BSP_LoadBrushes( lump_t *l )
// make the colbrush from the planes
out->colbrushf = CM_CollisionNewBrushFromPlanes( cmappool, out->numsides, planes, out->contents );
}
if( planes ) Mem_Free( planes );
}
/*
@ -537,43 +594,60 @@ BSP_LoadVerts
void IBSP_LoadVertexes( lump_t *l )
{
dvertexq_t *in;
cpointf_t *out;
int i, count;
vec3_t *out;
int i;
in = (void *)(cms.base + l->fileofs);
if( l->filelen % sizeof( *in )) Host_Error( "BSP_LoadVertexes: funny lump size\n" );
count = l->filelen / sizeof( *in );
cm.vertices = out = Mem_Alloc( cmappool, count * sizeof( *out ));
cm.numverts = l->filelen / sizeof( *in );
cm.vertices = out = Mem_Alloc( cmappool, cm.numverts * sizeof( *out ));
for( i = 0; i < count; i++, in++ )
for( i = 0; i < cm.numverts; i++, in++ )
{
out[i].v[0] = LittleFloat( in->point[0] );
out[i].v[1] = LittleFloat( in->point[1] );
out[i].v[2] = LittleFloat( in->point[2] );
out[i][0] = LittleFloat( in->point[0] );
out[i][1] = LittleFloat( in->point[1] );
out[i][2] = LittleFloat( in->point[2] );
}
}
void RBSP_LoadVertexes( lump_t *l )
{
dvertexr_t *in;
cpointf_t *out;
int i, count;
vec3_t *out;
int i;
in = (void *)(cms.base + l->fileofs);
if( l->filelen % sizeof( *in )) Host_Error( "BSP_LoadVertexes: funny lump size\n" );
count = l->filelen / sizeof( *in );
cm.vertices = out = Mem_Alloc( cmappool, count * sizeof( *out ));
cm.numverts = l->filelen / sizeof( *in );
cm.vertices = out = Mem_Alloc( cmappool, cm.numverts * sizeof( *out ));
for( i = 0; i < count; i++, in++ )
for( i = 0; i < cm.numverts; i++, in++ )
{
out[i].v[0] = LittleFloat( in->point[0] );
out[i].v[1] = LittleFloat( in->point[1] );
out[i].v[2] = LittleFloat( in->point[2] );
out[i][0] = LittleFloat( in->point[0] );
out[i][1] = LittleFloat( in->point[1] );
out[i][2] = LittleFloat( in->point[2] );
}
}
/*
=================
BSP_LoadEdges
=================
*/
void BSP_LoadIndexes( lump_t *l )
{
int *in, count;
in = (void *)(cms.base + l->fileofs);
if( l->filelen % sizeof( *in )) Host_Error( "BSP_LoadIndices: funny lump size\n" );
count = l->filelen / sizeof( *in );
// just for get number of triangles
cm.numtriangles = count / 3;
}
/*
=================
BSP_LoadSurfaces
@ -581,24 +655,202 @@ BSP_LoadSurfaces
*/
void IBSP_LoadSurfaces( lump_t *l )
{
dsurfaceq_t *in;
csurface_t *out;
int i;
in = (void *)(cms.base + l->fileofs);
dsurfaceq_t *in, *oldin;
csurface_t *out, *oldout;
int i, j, type;
int firstvertex, numverts, firstelem, numtriangles, finalvertices, finaltriangles;
int patchsize[2], xtess, ytess, cxtess, cytess, finalwidth, finalheight;
float *originalvertex3f;
patchtess_t *patchtess = NULL;
int patchtesscount = 0;
bool again;
in = oldin = (void *)(cms.base + l->fileofs);
if( l->filelen % sizeof( *in )) Host_Error( "BSP_LoadSurfaces: funny lump size\n" );
cm.numsurfaces = l->filelen / sizeof( *in );
cm.surfaces = out = Mem_Alloc( cmappool, cm.numsurfaces * sizeof( *out ));
cm.surfaces = out = oldout = Mem_Alloc( cmappool, cm.numsurfaces * sizeof( *out ));
if( cm.numsurfaces > 0 )
patchtess = (patchtess_t*) Mem_Alloc( cmappool, cm.numsurfaces * sizeof( *patchtess ));
Msg( "BSP_LoadSurfaces\n" );
for( i = 0; i < cm.numsurfaces; i++, in++, out++)
{
type = LittleLong( in->facetype );
// check face type first
switch( type )
{
case MST_PLANAR:
case MST_PATCH:
case MST_TRISURF:
case MST_FLARE:
break;
default:
MsgDev( D_ERROR, "BSP_LoadSurfaces: face #%i: unknown face type %i\n", i, type );
continue;
}
out->surfaceType = type;
out->shadernum = LittleLong( in->shadernum );
out->surfaceType = LittleLong( in->facetype );
out->firstvertex = LittleLong( in->firstvert );
out->numvertices = LittleLong( in->numverts );
// out->numtriangles = LittleLong( in->numelems ) / 3;
firstvertex = LittleLong( in->firstvert );
numverts = LittleLong( in->numverts );
firstelem = LittleLong( in->firstelem );
numtriangles = LittleLong( in->numelems ) / 3;
if( numtriangles * 3 != LittleLong( in->numelems ))
{
MsgDev( D_ERROR, "BSP_LoadSurfaces: face #%i (texture \"%s\"): numelements %i is not a multiple of 3\n", i, CM_TexName( out->shadernum ), LittleLong( in->numelems ));
continue;
}
if( firstvertex < 0 || firstvertex + numverts > cm.numverts )
{
MsgDev( D_ERROR, "BSP_LoadSurfaces: face #%i (texture \"%s\"): invalid vertex range %i : %i (%i vertices)\n", i, CM_TexName( out->shadernum ), firstvertex, firstvertex + numverts, cm.numverts );
continue;
}
if( firstelem < 0 || firstelem + numtriangles * 3 > cm.numtriangles * 3 )
{
MsgDev( D_ERROR, "BSP_LoadSurfaces: face #%i (texture \"%s\"): invalid element range %i : %i (%i elements)\n", i, CM_TexName( out->shadernum ), firstelem, firstelem + numtriangles * 3, cm.numtriangles * 3);
continue;
}
switch( type )
{
case MST_PLANAR:
case MST_TRISURF:
break; // no processing necessary
case MST_PATCH:
patchsize[0] = LittleLong( in->patch_cp[0] );
patchsize[1] = LittleLong( in->patch_cp[1] );
if( numverts != (patchsize[0] * patchsize[1]) || patchsize[0] < 3 || patchsize[1] < 3 || !(patchsize[0] & 1) || !(patchsize[1] & 1) || patchsize[0] * patchsize[1] >= 4225 )
{
MsgDev( D_ERROR, "BSP_LoadSurfaces: face #%i (texture \"%s\"): invalid patchsize %ix%i\n", i, CM_TexName( out->shadernum ), patchsize[0], patchsize[1]);
continue;
}
originalvertex3f = (float *)(cm.vertices + firstvertex);
// convert patch to MST_TRISURF
xtess = CM_PatchTesselationOnX( patchsize[0], patchsize[1], 3, originalvertex3f, 15.0f );
ytess = CM_PatchTesselationOnY( patchsize[0], patchsize[1], 3, originalvertex3f, 15.0f );
xtess = bound( 0, xtess, 1024 );
ytess = bound( 0, ytess, 1024 );
cxtess = CM_PatchTesselationOnX( patchsize[0], patchsize[1], 3, originalvertex3f, 15.0f );
cytess = CM_PatchTesselationOnY( patchsize[0], patchsize[1], 3, originalvertex3f, 15.0f );
cxtess = bound( 0, cxtess, 1024 );
cytess = bound( 0, cytess, 1024 );
Msg( "PatchTesselation: [%i] %i, %i (triangles %i)\n", i, cxtess, cytess, numtriangles );
// store it for the LOD grouping step
patchtess[patchtesscount].info.xsize = patchsize[0];
patchtess[patchtesscount].info.ysize = patchsize[1];
patchtess[patchtesscount].info.lods[PATCH_LOD_VISUAL].xtess = xtess;
patchtess[patchtesscount].info.lods[PATCH_LOD_VISUAL].ytess = ytess;
patchtess[patchtesscount].info.lods[PATCH_LOD_COLLISION].xtess = cxtess;
patchtess[patchtesscount].info.lods[PATCH_LOD_COLLISION].ytess = cytess;
patchtess[patchtesscount].surface_id = i;
patchtess[patchtesscount].lodgroup[0] = in->mins[0];
patchtess[patchtesscount].lodgroup[1] = in->mins[1];
patchtess[patchtesscount].lodgroup[2] = in->mins[2];
patchtess[patchtesscount].lodgroup[3] = in->maxs[0];
patchtess[patchtesscount].lodgroup[4] = in->maxs[1];
patchtess[patchtesscount].lodgroup[5] = in->maxs[2];
patchtess[patchtesscount].originalvertex3f = originalvertex3f;
patchtesscount++;
case MST_FLARE:
// ignore collisions at all
continue;
}
out->firstvertex = firstvertex;
out->numvertices = numverts;
}
// fix patches tesselations so that they make no seams
do
{
again = false;
for( i = 0; i < patchtesscount; ++i )
{
for( j = i+1; j < patchtesscount; ++j )
{
if( !PATCHTESS_SAME_LODGROUP( patchtess[i], patchtess[j] ))
continue;
if( CM_PatchAdjustTesselation( 3, &patchtess[i].info, patchtess[i].originalvertex3f, &patchtess[j].info, patchtess[j].originalvertex3f ))
again = true;
}
}
} while( again );
in = oldin;
out = oldout;
for( i = 0; i < cm.numsurfaces; i++, in++, out++)
{
firstvertex = LittleLong( in->firstvert );
switch( out->surfaceType )
{
case MST_PLANAR:
case MST_TRISURF:
break;
case MST_PATCH:
patchsize[0] = LittleLong( in->patch_cp[0] );
patchsize[1] = LittleLong( in->patch_cp[1] );
originalvertex3f = (float *)(cm.vertices + firstvertex);
xtess = ytess = cxtess = cytess = -1;
for( j = 0; j < patchtesscount; ++j )
{
if( patchtess[j].surface_id == i )
{
xtess = patchtess[j].info.lods[PATCH_LOD_VISUAL].xtess;
ytess = patchtess[j].info.lods[PATCH_LOD_VISUAL].ytess;
cxtess = patchtess[j].info.lods[PATCH_LOD_COLLISION].xtess;
cytess = patchtess[j].info.lods[PATCH_LOD_COLLISION].ytess;
break;
}
}
if( xtess == -1 )
{
MsgDev( D_ERROR, "patch %d isn't preprocessed?!?\n", i );
xtess = ytess = cxtess = cytess = 0;
}
// build the lower quality collision geometry
finalwidth = CM_PatchDimForTess( patchsize[0], cxtess );
finalheight = CM_PatchDimForTess( patchsize[1], cytess );
finalvertices = finalwidth * finalheight;
finaltriangles = (finalwidth - 1) * (finalheight - 1) * 2;
out->vertices = (float *)Mem_Alloc( cmappool, sizeof( float[3] ) * finalvertices );
out->indices = (int *)Mem_Alloc( cmappool, sizeof( int[3] ) * finaltriangles );
out->numvertices = finalvertices;
out->numtriangles = finaltriangles;
CM_PatchTesselateFloat( 3, sizeof( float[3] ), out->vertices, patchsize[0], patchsize[1], sizeof( float[3] ), originalvertex3f, cxtess, cytess );
CM_PatchTriangleElements( out->indices, finalwidth, finalheight, 0 );
CM_SnapVertices( 3, out->numvertices, out->vertices, 1 );
out->numtriangles = CM_RemoveDegenerateTriangles( out->numtriangles, out->indices, out->indices, out->vertices );
Msg( "Genarate patch with %i triangles\n", out->numtriangles );
break;
case MST_FLARE:
continue;
default:
MsgDev( D_ERROR, "BSP_LoadSurfaces: face #%i: unknown face type %i\n", i, type );
continue;
}
// calculate a bounding box
VectorCopy( in->mins, out->mins );
VectorCopy( in->maxs, out->maxs );
}
if( patchtess ) Mem_Free( patchtess );
}
void RBSP_LoadSurfaces( lump_t *l )
@ -680,6 +932,7 @@ static void BSP_RecursiveSetParent( cnode_t *node, cnode_t *parent )
csurface_t *m_surface = cm.surfaces + leaf->firstleafsurface[i];
if( m_surface->numtriangles )
{
Msg( "FOUND COLLISION PATCH\n" );
leaf->havepatches = true;
leaf->contents |= cm.shaders[m_surface->shadernum].contents;
}
@ -762,6 +1015,7 @@ void CM_LoadBSP( const void *buffer )
// bsplib uses light version of loading
IBSP_LoadVertexes( &header.lumps[LUMP_VERTEXES] );
BSP_LoadIndexes( &header.lumps[LUMP_ELEMENTS] );
BSP_LoadShaders( &header.lumps[LUMP_SHADERS] );
IBSP_LoadSurfaces( &header.lumps[LUMP_SURFACES] );
BSP_LoadModels( &header.lumps[LUMP_MODELS] );
@ -939,6 +1193,7 @@ cmodel_t *CM_BeginRegistration( const char *name, bool clientload, uint *checksu
IBSP_LoadBrushSides( &hdr->lumps[LUMP_BRUSHSIDES] );
BSP_LoadBrushes( &hdr->lumps[LUMP_BRUSHES] );
IBSP_LoadVertexes( &hdr->lumps[LUMP_VERTEXES] );
BSP_LoadIndexes( &hdr->lumps[LUMP_ELEMENTS] );
IBSP_LoadSurfaces( &hdr->lumps[LUMP_SURFACES] ); // used only for generate NewtonCollisionTree
BSP_LoadLeafBrushes( &hdr->lumps[LUMP_LEAFBRUSHES] );
BSP_LoadLeafSurfaces( &hdr->lumps[LUMP_LEAFSURFACES] );

View File

@ -6,13 +6,15 @@
--------------------Configuration: physic - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP1098.tmp" with contents
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP578.tmp" with contents
[
/nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../public" /I "../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\physic\!debug/" /Fo"..\temp\physic\!debug/" /Fd"..\temp\physic\!debug/" /FD /GZ /c
"D:\Xash3D\src_main\physic\cm_portals.c"
"D:\Xash3D\src_main\physic\cm_collision.c"
"D:\Xash3D\src_main\physic\cm_model.c"
"D:\Xash3D\src_main\physic\cm_trace.c"
]
Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP1098.tmp"
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP1099.tmp" with contents
Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP578.tmp"
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP579.tmp" with contents
[
user32.lib msvcrtd.lib newton.lib opengl32.lib /nologo /dll /incremental:yes /pdb:"..\temp\physic\!debug/physic.pdb" /debug /machine:I386 /nodefaultlib:"libc.lib" /out:"..\temp\physic\!debug/physic.dll" /implib:"..\temp\physic\!debug/physic.lib" /pdbtype:sept
"\Xash3D\src_main\temp\physic\!debug\cm_callback.obj"
@ -29,16 +31,20 @@ user32.lib msvcrtd.lib newton.lib opengl32.lib /nologo /dll /incremental:yes /pd
"\Xash3D\src_main\temp\physic\!debug\cm_utils.obj"
"\Xash3D\src_main\temp\physic\!debug\physic.obj"
]
Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP1099.tmp"
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP109A.bat" with contents
Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP579.tmp"
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP57A.bat" with contents
[
@echo off
copy \Xash3D\src_main\temp\physic\!debug\physic.dll "D:\Xash3D\bin\physic.dll"
]
Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP109A.bat"
Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP57A.bat"
Compiling...
cm_portals.c
cm_collision.c
cm_model.c
cm_trace.c
Generating Code...
Linking...
Creating library ..\temp\physic\!debug/physic.lib and object ..\temp\physic\!debug/physic.exp
<h3>Output Window</h3>
Performing Custom Build Step on \Xash3D\src_main\temp\physic\!debug\physic.dll
‘ª®¯¨à®¢ ­® ä ©«®¢: 1.

View File

@ -1712,7 +1712,8 @@ void R_ShutdownImages( void )
R_FreeImageBuffers ();
for( i = 0; i < r_numImages; i++ )
Mem_Free( images[i].name );
if( images[i].name )
Mem_Free( images[i].name );
if( r_imagePathBuf )
Mem_Free( r_imagePathBuf );

View File

@ -2039,6 +2039,7 @@ bool R_AddPolyToScene( const poly_t *poly )
*dp = *poly;
if( dp->numverts > MAX_POLY_VERTS )
dp->numverts = MAX_POLY_VERTS;
dp->shader = &r_shaders[poly->shadernum];
return true;
}
return false;

View File

@ -790,11 +790,12 @@ Mod_LoadShaderrefs
*/
static void Mod_LoadShaderrefs( const lump_t *l )
{
int i, count;
int contents;
dshader_t *in;
mshaderref_t *out;
int i, count;
int contents;
dshader_t *in;
mshaderref_t *out;
cvar_t *scr_loading = Cvar_Get( "scr_loading", "0", 0, "loading bar progress" );
in = ( void * )( mod_base + l->fileofs );
if( l->filelen % sizeof( *in ) )
Host_Error( "Mod_LoadShaderrefs: funny lump size in %s\n", loadmodel->name );
@ -806,6 +807,9 @@ static void Mod_LoadShaderrefs( const lump_t *l )
for( i = 0; i < count; i++, in++, out++ )
{
Cvar_SetValue( "scr_loading", scr_loading->value + 50.0f / count );
if( ri.UpdateScreen ) ri.UpdateScreen();
com.strncpy( out->name, in->name, sizeof( out->name ) );
out->flags = LittleLong( in->surfaceFlags );
contents = LittleLong( in->contentFlags );

View File

@ -1118,6 +1118,8 @@ void R_Shutdown( bool full )
// free shaders, models, etc.
R_FreeMedia();
Mem_FreePool( &r_temppool );
// shutdown rendering backend
R_BackendShutdown();

View File

@ -6,6 +6,52 @@
--------------------Configuration: render - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP58A.tmp" with contents
[
/nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../public" /I "../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\render\!debug/" /Fo"..\temp\render\!debug/" /Fd"..\temp\render\!debug/" /FD /c
"D:\Xash3D\src_main\render\r_model.c"
]
Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP58A.tmp"
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP58B.tmp" with contents
[
msvcrtd.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..\temp\render\!debug/render.pdb" /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"..\temp\render\!debug/render.dll" /implib:"..\temp\render\!debug/render.lib" /pdbtype:sept
"\Xash3D\src_main\temp\render\!debug\cin.obj"
"\Xash3D\src_main\temp\render\!debug\glw_imp.obj"
"\Xash3D\src_main\temp\render\!debug\qgl_win.obj"
"\Xash3D\src_main\temp\render\!debug\r_alias.obj"
"\Xash3D\src_main\temp\render\!debug\r_backend.obj"
"\Xash3D\src_main\temp\render\!debug\r_bloom.obj"
"\Xash3D\src_main\temp\render\!debug\r_cin.obj"
"\Xash3D\src_main\temp\render\!debug\r_cull.obj"
"\Xash3D\src_main\temp\render\!debug\r_image.obj"
"\Xash3D\src_main\temp\render\!debug\r_light.obj"
"\Xash3D\src_main\temp\render\!debug\r_main.obj"
"\Xash3D\src_main\temp\render\!debug\r_math.obj"
"\Xash3D\src_main\temp\render\!debug\r_mesh.obj"
"\Xash3D\src_main\temp\render\!debug\r_model.obj"
"\Xash3D\src_main\temp\render\!debug\r_poly.obj"
"\Xash3D\src_main\temp\render\!debug\r_program.obj"
"\Xash3D\src_main\temp\render\!debug\r_register.obj"
"\Xash3D\src_main\temp\render\!debug\r_shader.obj"
"\Xash3D\src_main\temp\render\!debug\r_shadow.obj"
"\Xash3D\src_main\temp\render\!debug\r_skin.obj"
"\Xash3D\src_main\temp\render\!debug\r_skm.obj"
"\Xash3D\src_main\temp\render\!debug\r_sky.obj"
"\Xash3D\src_main\temp\render\!debug\r_surf.obj"
]
Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP58B.tmp"
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP58C.bat" with contents
[
@echo off
copy \Xash3D\src_main\temp\render\!debug\render.dll "D:\Xash3D\bin\render.dll"
]
Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP58C.bat"
Compiling...
r_model.c
Linking...
<h3>Output Window</h3>
Performing Custom Build Step on \Xash3D\src_main\temp\render\!debug\render.dll
‘ª®¯¨à®¢ ­® ä ©«®¢: 1.

View File

@ -1,100 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: server - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP101D.tmp" with contents
[
/nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "ents" /I "game" /I "global" /I "monsters" /I "../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\server\!debug/" /Fo"..\temp\server\!debug/" /Fd"..\temp\server\!debug/" /FD /c
"D:\Xash3D\src_main\server\monsters\player.cpp"
]
Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP101D.tmp"
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP101E.tmp" with contents
[
msvcrtd.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..\temp\server\!debug/server.pdb" /debug /machine:I386 /nodefaultlib:"libc.lib" /def:".\server.def" /out:"..\temp\server\!debug/server.dll" /implib:"..\temp\server\!debug/server.lib" /pdbtype:sept
"\Xash3D\src_main\temp\server\!debug\ai_sound.obj"
"\Xash3D\src_main\temp\server\!debug\animating.obj"
"\Xash3D\src_main\temp\server\!debug\animation.obj"
"\Xash3D\src_main\temp\server\!debug\apache.obj"
"\Xash3D\src_main\temp\server\!debug\barnacle.obj"
"\Xash3D\src_main\temp\server\!debug\barney.obj"
"\Xash3D\src_main\temp\server\!debug\basebrush.obj"
"\Xash3D\src_main\temp\server\!debug\baseentity.obj"
"\Xash3D\src_main\temp\server\!debug\basefunc.obj"
"\Xash3D\src_main\temp\server\!debug\basefx.obj"
"\Xash3D\src_main\temp\server\!debug\baseinfo.obj"
"\Xash3D\src_main\temp\server\!debug\baseitem.obj"
"\Xash3D\src_main\temp\server\!debug\baselogic.obj"
"\Xash3D\src_main\temp\server\!debug\basemonster.obj"
"\Xash3D\src_main\temp\server\!debug\basemover.obj"
"\Xash3D\src_main\temp\server\!debug\baseother.obj"
"\Xash3D\src_main\temp\server\!debug\basepath.obj"
"\Xash3D\src_main\temp\server\!debug\basephys.obj"
"\Xash3D\src_main\temp\server\!debug\baserockets.obj"
"\Xash3D\src_main\temp\server\!debug\basetank.obj"
"\Xash3D\src_main\temp\server\!debug\basetrigger.obj"
"\Xash3D\src_main\temp\server\!debug\baseutil.obj"
"\Xash3D\src_main\temp\server\!debug\baseweapon.obj"
"\Xash3D\src_main\temp\server\!debug\baseworld.obj"
"\Xash3D\src_main\temp\server\!debug\client.obj"
"\Xash3D\src_main\temp\server\!debug\combat.obj"
"\Xash3D\src_main\temp\server\!debug\decals.obj"
"\Xash3D\src_main\temp\server\!debug\defaultai.obj"
"\Xash3D\src_main\temp\server\!debug\dll_int.obj"
"\Xash3D\src_main\temp\server\!debug\flyingmonster.obj"
"\Xash3D\src_main\temp\server\!debug\game.obj"
"\Xash3D\src_main\temp\server\!debug\gamerules.obj"
"\Xash3D\src_main\temp\server\!debug\generic.obj"
"\Xash3D\src_main\temp\server\!debug\globals.obj"
"\Xash3D\src_main\temp\server\!debug\gman.obj"
"\Xash3D\src_main\temp\server\!debug\hassassin.obj"
"\Xash3D\src_main\temp\server\!debug\headcrab.obj"
"\Xash3D\src_main\temp\server\!debug\hgrunt.obj"
"\Xash3D\src_main\temp\server\!debug\leech.obj"
"\Xash3D\src_main\temp\server\!debug\legacy.obj"
"\Xash3D\src_main\temp\server\!debug\lights.obj"
"\Xash3D\src_main\temp\server\!debug\multiplay_gamerules.obj"
"\Xash3D\src_main\temp\server\!debug\nodes.obj"
"\Xash3D\src_main\temp\server\!debug\osprey.obj"
"\Xash3D\src_main\temp\server\!debug\parent.obj"
"\Xash3D\src_main\temp\server\!debug\player.obj"
"\Xash3D\src_main\temp\server\!debug\rat.obj"
"\Xash3D\src_main\temp\server\!debug\roach.obj"
"\Xash3D\src_main\temp\server\!debug\saverestore.obj"
"\Xash3D\src_main\temp\server\!debug\scientist.obj"
"\Xash3D\src_main\temp\server\!debug\scripted.obj"
"\Xash3D\src_main\temp\server\!debug\sfx.obj"
"\Xash3D\src_main\temp\server\!debug\singleplay_gamerules.obj"
"\Xash3D\src_main\temp\server\!debug\sound.obj"
"\Xash3D\src_main\temp\server\!debug\squadmonster.obj"
"\Xash3D\src_main\temp\server\!debug\talkmonster.obj"
"\Xash3D\src_main\temp\server\!debug\teamplay_gamerules.obj"
"\Xash3D\src_main\temp\server\!debug\turret.obj"
"\Xash3D\src_main\temp\server\!debug\utils.obj"
"\Xash3D\src_main\temp\server\!debug\weapon_generic.obj"
"\Xash3D\src_main\temp\server\!debug\zombie.obj"
]
Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP101E.tmp"
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP101F.bat" with contents
[
@echo off
copy \Xash3D\src_main\temp\server\!debug\server.dll "D:\Xash3D\bin\server.dll"
]
Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP101F.bat"
Compiling...
player.cpp
Linking...
<h3>Output Window</h3>
Performing Custom Build Step on \Xash3D\src_main\temp\server\!debug\server.dll
‘ª®¯¨à®¢ ­® ä ©«®¢: 1.
<h3>Results</h3>
server.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -85,7 +85,8 @@ Beta 13.12.08
54. q3/rbsp bsp format OK
55. dedicated conolse hanging commands
56. renderer viewport bug
57. shutdown crash
57. shutdown crash OK
58. physic.dll finish collisions
Ñïèñîê äîñòóïíûõ ðåíäåðåðîâ: ×òî â íèõ èíòåðåñíîãî
0. Q3Fusion (Mirrors, Portals)