00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "cm_local.h"
00025
00026 #ifdef BSPC
00027
00028 #include "../bspc/l_qfiles.h"
00029
00030 void SetPlaneSignbits (cplane_t *out) {
00031 int bits, j;
00032
00033
00034 bits = 0;
00035 for (j=0 ; j<3 ; j++) {
00036 if (out->normal[j] < 0) {
00037 bits |= 1<<j;
00038 }
00039 }
00040 out->signbits = bits;
00041 }
00042 #endif //BSPC
00043
00044
00045
00046 #define BOX_BRUSHES 1
00047 #define BOX_SIDES 6
00048 #define BOX_LEAFS 2
00049 #define BOX_PLANES 12
00050
00051 #define LL(x) x=LittleLong(x)
00052
00053
00054 clipMap_t cm;
00055 int c_pointcontents;
00056 int c_traces, c_brush_traces, c_patch_traces;
00057
00058
00059 byte *cmod_base;
00060
00061 #ifndef BSPC
00062 cvar_t *cm_noAreas;
00063 cvar_t *cm_noCurves;
00064 cvar_t *cm_playerCurveClip;
00065 #endif
00066
00067 cmodel_t box_model;
00068 cplane_t *box_planes;
00069 cbrush_t *box_brush;
00070
00071
00072
00073 void CM_InitBoxHull (void);
00074 void CM_FloodAreaConnections (void);
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 void CMod_LoadShaders( lump_t *l ) {
00091 dshader_t *in, *out;
00092 int i, count;
00093
00094 in = (void *)(cmod_base + l->fileofs);
00095 if (l->filelen % sizeof(*in)) {
00096 Com_Error (ERR_DROP, "CMod_LoadShaders: funny lump size");
00097 }
00098 count = l->filelen / sizeof(*in);
00099
00100 if (count < 1) {
00101 Com_Error (ERR_DROP, "Map with no shaders");
00102 }
00103 cm.shaders = Hunk_Alloc( count * sizeof( *cm.shaders ), h_high );
00104 cm.numShaders = count;
00105
00106 Com_Memcpy( cm.shaders, in, count * sizeof( *cm.shaders ) );
00107
00108 out = cm.shaders;
00109 for ( i=0 ; i<count ; i++, in++, out++ ) {
00110 out->contentFlags = LittleLong( out->contentFlags );
00111 out->surfaceFlags = LittleLong( out->surfaceFlags );
00112 }
00113 }
00114
00115
00116
00117
00118
00119
00120
00121 void CMod_LoadSubmodels( lump_t *l ) {
00122 dmodel_t *in;
00123 cmodel_t *out;
00124 int i, j, count;
00125 int *indexes;
00126
00127 in = (void *)(cmod_base + l->fileofs);
00128 if (l->filelen % sizeof(*in))
00129 Com_Error (ERR_DROP, "CMod_LoadSubmodels: funny lump size");
00130 count = l->filelen / sizeof(*in);
00131
00132 if (count < 1)
00133 Com_Error (ERR_DROP, "Map with no models");
00134 cm.cmodels = Hunk_Alloc( count * sizeof( *cm.cmodels ), h_high );
00135 cm.numSubModels = count;
00136
00137 if ( count > MAX_SUBMODELS ) {
00138 Com_Error( ERR_DROP, "MAX_SUBMODELS exceeded" );
00139 }
00140
00141 for ( i=0 ; i<count ; i++, in++, out++)
00142 {
00143 out = &cm.cmodels[i];
00144
00145 for (j=0 ; j<3 ; j++)
00146 {
00147 out->mins[j] = LittleFloat (in->mins[j]) - 1;
00148 out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
00149 }
00150
00151 if ( i == 0 ) {
00152 continue;
00153 }
00154
00155
00156 out->leaf.numLeafBrushes = LittleLong( in->numBrushes );
00157 indexes = Hunk_Alloc( out->leaf.numLeafBrushes * 4, h_high );
00158 out->leaf.firstLeafBrush = indexes - cm.leafbrushes;
00159 for ( j = 0 ; j < out->leaf.numLeafBrushes ; j++ ) {
00160 indexes[j] = LittleLong( in->firstBrush ) + j;
00161 }
00162
00163 out->leaf.numLeafSurfaces = LittleLong( in->numSurfaces );
00164 indexes = Hunk_Alloc( out->leaf.numLeafSurfaces * 4, h_high );
00165 out->leaf.firstLeafSurface = indexes - cm.leafsurfaces;
00166 for ( j = 0 ; j < out->leaf.numLeafSurfaces ; j++ ) {
00167 indexes[j] = LittleLong( in->firstSurface ) + j;
00168 }
00169 }
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179 void CMod_LoadNodes( lump_t *l ) {
00180 dnode_t *in;
00181 int child;
00182 cNode_t *out;
00183 int i, j, count;
00184
00185 in = (void *)(cmod_base + l->fileofs);
00186 if (l->filelen % sizeof(*in))
00187 Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
00188 count = l->filelen / sizeof(*in);
00189
00190 if (count < 1)
00191 Com_Error (ERR_DROP, "Map has no nodes");
00192 cm.nodes = Hunk_Alloc( count * sizeof( *cm.nodes ), h_high );
00193 cm.numNodes = count;
00194
00195 out = cm.nodes;
00196
00197 for (i=0 ; i<count ; i++, out++, in++)
00198 {
00199 out->plane = cm.planes + LittleLong( in->planeNum );
00200 for (j=0 ; j<2 ; j++)
00201 {
00202 child = LittleLong (in->children[j]);
00203 out->children[j] = child;
00204 }
00205 }
00206
00207 }
00208
00209
00210
00211
00212
00213
00214
00215 void CM_BoundBrush( cbrush_t *b ) {
00216 b->bounds[0][0] = -b->sides[0].plane->dist;
00217 b->bounds[1][0] = b->sides[1].plane->dist;
00218
00219 b->bounds[0][1] = -b->sides[2].plane->dist;
00220 b->bounds[1][1] = b->sides[3].plane->dist;
00221
00222 b->bounds[0][2] = -b->sides[4].plane->dist;
00223 b->bounds[1][2] = b->sides[5].plane->dist;
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233 void CMod_LoadBrushes( lump_t *l ) {
00234 dbrush_t *in;
00235 cbrush_t *out;
00236 int i, count;
00237
00238 in = (void *)(cmod_base + l->fileofs);
00239 if (l->filelen % sizeof(*in)) {
00240 Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
00241 }
00242 count = l->filelen / sizeof(*in);
00243
00244 cm.brushes = Hunk_Alloc( ( BOX_BRUSHES + count ) * sizeof( *cm.brushes ), h_high );
00245 cm.numBrushes = count;
00246
00247 out = cm.brushes;
00248
00249 for ( i=0 ; i<count ; i++, out++, in++ ) {
00250 out->sides = cm.brushsides + LittleLong(in->firstSide);
00251 out->numsides = LittleLong(in->numSides);
00252
00253 out->shaderNum = LittleLong( in->shaderNum );
00254 if ( out->shaderNum < 0 || out->shaderNum >= cm.numShaders ) {
00255 Com_Error( ERR_DROP, "CMod_LoadBrushes: bad shaderNum: %i", out->shaderNum );
00256 }
00257 out->contents = cm.shaders[out->shaderNum].contentFlags;
00258
00259 CM_BoundBrush( out );
00260 }
00261
00262 }
00263
00264
00265
00266
00267
00268
00269 void CMod_LoadLeafs (lump_t *l)
00270 {
00271 int i;
00272 cLeaf_t *out;
00273 dleaf_t *in;
00274 int count;
00275
00276 in = (void *)(cmod_base + l->fileofs);
00277 if (l->filelen % sizeof(*in))
00278 Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
00279 count = l->filelen / sizeof(*in);
00280
00281 if (count < 1)
00282 Com_Error (ERR_DROP, "Map with no leafs");
00283
00284 cm.leafs = Hunk_Alloc( ( BOX_LEAFS + count ) * sizeof( *cm.leafs ), h_high );
00285 cm.numLeafs = count;
00286
00287 out = cm.leafs;
00288 for ( i=0 ; i<count ; i++, in++, out++)
00289 {
00290 out->cluster = LittleLong (in->cluster);
00291 out->area = LittleLong (in->area);
00292 out->firstLeafBrush = LittleLong (in->firstLeafBrush);
00293 out->numLeafBrushes = LittleLong (in->numLeafBrushes);
00294 out->firstLeafSurface = LittleLong (in->firstLeafSurface);
00295 out->numLeafSurfaces = LittleLong (in->numLeafSurfaces);
00296
00297 if (out->cluster >= cm.numClusters)
00298 cm.numClusters = out->cluster + 1;
00299 if (out->area >= cm.numAreas)
00300 cm.numAreas = out->area + 1;
00301 }
00302
00303 cm.areas = Hunk_Alloc( cm.numAreas * sizeof( *cm.areas ), h_high );
00304 cm.areaPortals = Hunk_Alloc( cm.numAreas * cm.numAreas * sizeof( *cm.areaPortals ), h_high );
00305 }
00306
00307
00308
00309
00310
00311
00312 void CMod_LoadPlanes (lump_t *l)
00313 {
00314 int i, j;
00315 cplane_t *out;
00316 dplane_t *in;
00317 int count;
00318 int bits;
00319
00320 in = (void *)(cmod_base + l->fileofs);
00321 if (l->filelen % sizeof(*in))
00322 Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
00323 count = l->filelen / sizeof(*in);
00324
00325 if (count < 1)
00326 Com_Error (ERR_DROP, "Map with no planes");
00327 cm.planes = Hunk_Alloc( ( BOX_PLANES + count ) * sizeof( *cm.planes ), h_high );
00328 cm.numPlanes = count;
00329
00330 out = cm.planes;
00331
00332 for ( i=0 ; i<count ; i++, in++, out++)
00333 {
00334 bits = 0;
00335 for (j=0 ; j<3 ; j++)
00336 {
00337 out->normal[j] = LittleFloat (in->normal[j]);
00338 if (out->normal[j] < 0)
00339 bits |= 1<<j;
00340 }
00341
00342 out->dist = LittleFloat (in->dist);
00343 out->type = PlaneTypeForNormal( out->normal );
00344 out->signbits = bits;
00345 }
00346 }
00347
00348
00349
00350
00351
00352
00353 void CMod_LoadLeafBrushes (lump_t *l)
00354 {
00355 int i;
00356 int *out;
00357 int *in;
00358 int count;
00359
00360 in = (void *)(cmod_base + l->fileofs);
00361 if (l->filelen % sizeof(*in))
00362 Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
00363 count = l->filelen / sizeof(*in);
00364
00365 cm.leafbrushes = Hunk_Alloc( (count + BOX_BRUSHES) * sizeof( *cm.leafbrushes ), h_high );
00366 cm.numLeafBrushes = count;
00367
00368 out = cm.leafbrushes;
00369
00370 for ( i=0 ; i<count ; i++, in++, out++) {
00371 *out = LittleLong (*in);
00372 }
00373 }
00374
00375
00376
00377
00378
00379
00380 void CMod_LoadLeafSurfaces( lump_t *l )
00381 {
00382 int i;
00383 int *out;
00384 int *in;
00385 int count;
00386
00387 in = (void *)(cmod_base + l->fileofs);
00388 if (l->filelen % sizeof(*in))
00389 Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
00390 count = l->filelen / sizeof(*in);
00391
00392 cm.leafsurfaces = Hunk_Alloc( count * sizeof( *cm.leafsurfaces ), h_high );
00393 cm.numLeafSurfaces = count;
00394
00395 out = cm.leafsurfaces;
00396
00397 for ( i=0 ; i<count ; i++, in++, out++) {
00398 *out = LittleLong (*in);
00399 }
00400 }
00401
00402
00403
00404
00405
00406
00407 void CMod_LoadBrushSides (lump_t *l)
00408 {
00409 int i;
00410 cbrushside_t *out;
00411 dbrushside_t *in;
00412 int count;
00413 int num;
00414
00415 in = (void *)(cmod_base + l->fileofs);
00416 if ( l->filelen % sizeof(*in) ) {
00417 Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
00418 }
00419 count = l->filelen / sizeof(*in);
00420
00421 cm.brushsides = Hunk_Alloc( ( BOX_SIDES + count ) * sizeof( *cm.brushsides ), h_high );
00422 cm.numBrushSides = count;
00423
00424 out = cm.brushsides;
00425
00426 for ( i=0 ; i<count ; i++, in++, out++) {
00427 num = LittleLong( in->planeNum );
00428 out->plane = &cm.planes[num];
00429 out->shaderNum = LittleLong( in->shaderNum );
00430 if ( out->shaderNum < 0 || out->shaderNum >= cm.numShaders ) {
00431 Com_Error( ERR_DROP, "CMod_LoadBrushSides: bad shaderNum: %i", out->shaderNum );
00432 }
00433 out->surfaceFlags = cm.shaders[out->shaderNum].surfaceFlags;
00434 }
00435 }
00436
00437
00438
00439
00440
00441
00442
00443 void CMod_LoadEntityString( lump_t *l ) {
00444 cm.entityString = Hunk_Alloc( l->filelen, h_high );
00445 cm.numEntityChars = l->filelen;
00446 Com_Memcpy (cm.entityString, cmod_base + l->fileofs, l->filelen);
00447 }
00448
00449
00450
00451
00452
00453
00454 #define VIS_HEADER 8
00455 void CMod_LoadVisibility( lump_t *l ) {
00456 int len;
00457 byte *buf;
00458
00459 len = l->filelen;
00460 if ( !len ) {
00461 cm.clusterBytes = ( cm.numClusters + 31 ) & ~31;
00462 cm.visibility = Hunk_Alloc( cm.clusterBytes, h_high );
00463 Com_Memset( cm.visibility, 255, cm.clusterBytes );
00464 return;
00465 }
00466 buf = cmod_base + l->fileofs;
00467
00468 cm.vised = qtrue;
00469 cm.visibility = Hunk_Alloc( len, h_high );
00470 cm.numClusters = LittleLong( ((int *)buf)[0] );
00471 cm.clusterBytes = LittleLong( ((int *)buf)[1] );
00472 Com_Memcpy (cm.visibility, buf + VIS_HEADER, len - VIS_HEADER );
00473 }
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 #define MAX_PATCH_VERTS 1024
00484 void CMod_LoadPatches( lump_t *surfs, lump_t *verts ) {
00485 drawVert_t *dv, *dv_p;
00486 dsurface_t *in;
00487 int count;
00488 int i, j;
00489 int c;
00490 cPatch_t *patch;
00491 vec3_t points[MAX_PATCH_VERTS];
00492 int width, height;
00493 int shaderNum;
00494
00495 in = (void *)(cmod_base + surfs->fileofs);
00496 if (surfs->filelen % sizeof(*in))
00497 Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
00498 cm.numSurfaces = count = surfs->filelen / sizeof(*in);
00499 cm.surfaces = Hunk_Alloc( cm.numSurfaces * sizeof( cm.surfaces[0] ), h_high );
00500
00501 dv = (void *)(cmod_base + verts->fileofs);
00502 if (verts->filelen % sizeof(*dv))
00503 Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size");
00504
00505
00506
00507 for ( i = 0 ; i < count ; i++, in++ ) {
00508 if ( LittleLong( in->surfaceType ) != MST_PATCH ) {
00509 continue;
00510 }
00511
00512
00513 cm.surfaces[ i ] = patch = Hunk_Alloc( sizeof( *patch ), h_high );
00514
00515
00516 width = LittleLong( in->patchWidth );
00517 height = LittleLong( in->patchHeight );
00518 c = width * height;
00519 if ( c > MAX_PATCH_VERTS ) {
00520 Com_Error( ERR_DROP, "ParseMesh: MAX_PATCH_VERTS" );
00521 }
00522
00523 dv_p = dv + LittleLong( in->firstVert );
00524 for ( j = 0 ; j < c ; j++, dv_p++ ) {
00525 points[j][0] = LittleFloat( dv_p->xyz[0] );
00526 points[j][1] = LittleFloat( dv_p->xyz[1] );
00527 points[j][2] = LittleFloat( dv_p->xyz[2] );
00528 }
00529
00530 shaderNum = LittleLong( in->shaderNum );
00531 patch->contents = cm.shaders[shaderNum].contentFlags;
00532 patch->surfaceFlags = cm.shaders[shaderNum].surfaceFlags;
00533
00534
00535 patch->pc = CM_GeneratePatchCollide( width, height, points );
00536 }
00537 }
00538
00539
00540
00541 unsigned CM_LumpChecksum(lump_t *lump) {
00542 return LittleLong (Com_BlockChecksum (cmod_base + lump->fileofs, lump->filelen));
00543 }
00544
00545 unsigned CM_Checksum(dheader_t *header) {
00546 unsigned checksums[16];
00547 checksums[0] = CM_LumpChecksum(&header->lumps[LUMP_SHADERS]);
00548 checksums[1] = CM_LumpChecksum(&header->lumps[LUMP_LEAFS]);
00549 checksums[2] = CM_LumpChecksum(&header->lumps[LUMP_LEAFBRUSHES]);
00550 checksums[3] = CM_LumpChecksum(&header->lumps[LUMP_LEAFSURFACES]);
00551 checksums[4] = CM_LumpChecksum(&header->lumps[LUMP_PLANES]);
00552 checksums[5] = CM_LumpChecksum(&header->lumps[LUMP_BRUSHSIDES]);
00553 checksums[6] = CM_LumpChecksum(&header->lumps[LUMP_BRUSHES]);
00554 checksums[7] = CM_LumpChecksum(&header->lumps[LUMP_MODELS]);
00555 checksums[8] = CM_LumpChecksum(&header->lumps[LUMP_NODES]);
00556 checksums[9] = CM_LumpChecksum(&header->lumps[LUMP_SURFACES]);
00557 checksums[10] = CM_LumpChecksum(&header->lumps[LUMP_DRAWVERTS]);
00558
00559 return LittleLong(Com_BlockChecksum(checksums, 11 * 4));
00560 }
00561
00562
00563
00564
00565
00566
00567
00568
00569 void CM_LoadMap( const char *name, qboolean clientload, int *checksum ) {
00570 int *buf;
00571 int i;
00572 dheader_t header;
00573 int length;
00574 static unsigned last_checksum;
00575
00576 if ( !name || !name[0] ) {
00577 Com_Error( ERR_DROP, "CM_LoadMap: NULL name" );
00578 }
00579
00580 #ifndef BSPC
00581 cm_noAreas = Cvar_Get ("cm_noAreas", "0", CVAR_CHEAT);
00582 cm_noCurves = Cvar_Get ("cm_noCurves", "0", CVAR_CHEAT);
00583 cm_playerCurveClip = Cvar_Get ("cm_playerCurveClip", "1", CVAR_ARCHIVE|CVAR_CHEAT );
00584 #endif
00585 Com_DPrintf( "CM_LoadMap( %s, %i )\n", name, clientload );
00586
00587 if ( !strcmp( cm.name, name ) && clientload ) {
00588 *checksum = last_checksum;
00589 return;
00590 }
00591
00592
00593 Com_Memset( &cm, 0, sizeof( cm ) );
00594 CM_ClearLevelPatches();
00595
00596 if ( !name[0] ) {
00597 cm.numLeafs = 1;
00598 cm.numClusters = 1;
00599 cm.numAreas = 1;
00600 cm.cmodels = Hunk_Alloc( sizeof( *cm.cmodels ), h_high );
00601 *checksum = 0;
00602 return;
00603 }
00604
00605
00606
00607
00608 #ifndef BSPC
00609 length = FS_ReadFile( name, (void **)&buf );
00610 #else
00611 length = LoadQuakeFile((quakefile_t *) name, (void **)&buf);
00612 #endif
00613
00614 if ( !buf ) {
00615 Com_Error (ERR_DROP, "Couldn't load %s", name);
00616 }
00617
00618 last_checksum = LittleLong (Com_BlockChecksum (buf, length));
00619 *checksum = last_checksum;
00620
00621 header = *(dheader_t *)buf;
00622 for (i=0 ; i<sizeof(dheader_t)/4 ; i++) {
00623 ((int *)&header)[i] = LittleLong ( ((int *)&header)[i]);
00624 }
00625
00626 if ( header.version != BSP_VERSION ) {
00627 Com_Error (ERR_DROP, "CM_LoadMap: %s has wrong version number (%i should be %i)"
00628 , name, header.version, BSP_VERSION );
00629 }
00630
00631 cmod_base = (byte *)buf;
00632
00633
00634 CMod_LoadShaders( &header.lumps[LUMP_SHADERS] );
00635 CMod_LoadLeafs (&header.lumps[LUMP_LEAFS]);
00636 CMod_LoadLeafBrushes (&header.lumps[LUMP_LEAFBRUSHES]);
00637 CMod_LoadLeafSurfaces (&header.lumps[LUMP_LEAFSURFACES]);
00638 CMod_LoadPlanes (&header.lumps[LUMP_PLANES]);
00639 CMod_LoadBrushSides (&header.lumps[LUMP_BRUSHSIDES]);
00640 CMod_LoadBrushes (&header.lumps[LUMP_BRUSHES]);
00641 CMod_LoadSubmodels (&header.lumps[LUMP_MODELS]);
00642 CMod_LoadNodes (&header.lumps[LUMP_NODES]);
00643 CMod_LoadEntityString (&header.lumps[LUMP_ENTITIES]);
00644 CMod_LoadVisibility( &header.lumps[LUMP_VISIBILITY] );
00645 CMod_LoadPatches( &header.lumps[LUMP_SURFACES], &header.lumps[LUMP_DRAWVERTS] );
00646
00647
00648 FS_FreeFile (buf);
00649
00650 CM_InitBoxHull ();
00651
00652 CM_FloodAreaConnections ();
00653
00654
00655 if ( !clientload ) {
00656 Q_strncpyz( cm.name, name, sizeof( cm.name ) );
00657 }
00658 }
00659
00660
00661
00662
00663
00664
00665 void CM_ClearMap( void ) {
00666 Com_Memset( &cm, 0, sizeof( cm ) );
00667 CM_ClearLevelPatches();
00668 }
00669
00670
00671
00672
00673
00674
00675 cmodel_t *CM_ClipHandleToModel( clipHandle_t handle ) {
00676 if ( handle < 0 ) {
00677 Com_Error( ERR_DROP, "CM_ClipHandleToModel: bad handle %i", handle );
00678 }
00679 if ( handle < cm.numSubModels ) {
00680 return &cm.cmodels[handle];
00681 }
00682 if ( handle == BOX_MODEL_HANDLE ) {
00683 return &box_model;
00684 }
00685 if ( handle < MAX_SUBMODELS ) {
00686 Com_Error( ERR_DROP, "CM_ClipHandleToModel: bad handle %i < %i < %i",
00687 cm.numSubModels, handle, MAX_SUBMODELS );
00688 }
00689 Com_Error( ERR_DROP, "CM_ClipHandleToModel: bad handle %i", handle + MAX_SUBMODELS );
00690
00691 return NULL;
00692
00693 }
00694
00695
00696
00697
00698
00699
00700 clipHandle_t CM_InlineModel( int index ) {
00701 if ( index < 0 || index >= cm.numSubModels ) {
00702 Com_Error (ERR_DROP, "CM_InlineModel: bad number");
00703 }
00704 return index;
00705 }
00706
00707 int CM_NumClusters( void ) {
00708 return cm.numClusters;
00709 }
00710
00711 int CM_NumInlineModels( void ) {
00712 return cm.numSubModels;
00713 }
00714
00715 char *CM_EntityString( void ) {
00716 return cm.entityString;
00717 }
00718
00719 int CM_LeafCluster( int leafnum ) {
00720 if (leafnum < 0 || leafnum >= cm.numLeafs) {
00721 Com_Error (ERR_DROP, "CM_LeafCluster: bad number");
00722 }
00723 return cm.leafs[leafnum].cluster;
00724 }
00725
00726 int CM_LeafArea( int leafnum ) {
00727 if ( leafnum < 0 || leafnum >= cm.numLeafs ) {
00728 Com_Error (ERR_DROP, "CM_LeafArea: bad number");
00729 }
00730 return cm.leafs[leafnum].area;
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744 void CM_InitBoxHull (void)
00745 {
00746 int i;
00747 int side;
00748 cplane_t *p;
00749 cbrushside_t *s;
00750
00751 box_planes = &cm.planes[cm.numPlanes];
00752
00753 box_brush = &cm.brushes[cm.numBrushes];
00754 box_brush->numsides = 6;
00755 box_brush->sides = cm.brushsides + cm.numBrushSides;
00756 box_brush->contents = CONTENTS_BODY;
00757
00758 box_model.leaf.numLeafBrushes = 1;
00759
00760 box_model.leaf.firstLeafBrush = cm.numLeafBrushes;
00761 cm.leafbrushes[cm.numLeafBrushes] = cm.numBrushes;
00762
00763 for (i=0 ; i<6 ; i++)
00764 {
00765 side = i&1;
00766
00767
00768 s = &cm.brushsides[cm.numBrushSides+i];
00769 s->plane = cm.planes + (cm.numPlanes+i*2+side);
00770 s->surfaceFlags = 0;
00771
00772
00773 p = &box_planes[i*2];
00774 p->type = i>>1;
00775 p->signbits = 0;
00776 VectorClear (p->normal);
00777 p->normal[i>>1] = 1;
00778
00779 p = &box_planes[i*2+1];
00780 p->type = 3 + (i>>1);
00781 p->signbits = 0;
00782 VectorClear (p->normal);
00783 p->normal[i>>1] = -1;
00784
00785 SetPlaneSignbits( p );
00786 }
00787 }
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798 clipHandle_t CM_TempBoxModel( const vec3_t mins, const vec3_t maxs, int capsule ) {
00799
00800 VectorCopy( mins, box_model.mins );
00801 VectorCopy( maxs, box_model.maxs );
00802
00803 if ( capsule ) {
00804 return CAPSULE_MODEL_HANDLE;
00805 }
00806
00807 box_planes[0].dist = maxs[0];
00808 box_planes[1].dist = -maxs[0];
00809 box_planes[2].dist = mins[0];
00810 box_planes[3].dist = -mins[0];
00811 box_planes[4].dist = maxs[1];
00812 box_planes[5].dist = -maxs[1];
00813 box_planes[6].dist = mins[1];
00814 box_planes[7].dist = -mins[1];
00815 box_planes[8].dist = maxs[2];
00816 box_planes[9].dist = -maxs[2];
00817 box_planes[10].dist = mins[2];
00818 box_planes[11].dist = -mins[2];
00819
00820 VectorCopy( mins, box_brush->bounds[0] );
00821 VectorCopy( maxs, box_brush->bounds[1] );
00822
00823 return BOX_MODEL_HANDLE;
00824 }
00825
00826
00827
00828
00829
00830
00831 void CM_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs ) {
00832 cmodel_t *cmod;
00833
00834 cmod = CM_ClipHandleToModel( model );
00835 VectorCopy( cmod->mins, mins );
00836 VectorCopy( cmod->maxs, maxs );
00837 }
00838
00839