| 63 |
*/ |
*/ |
| 64 |
void CreateBrushFaces (void) |
void CreateBrushFaces (void) |
| 65 |
{ |
{ |
| 66 |
int i,j, k, rotate; |
int i,j, k; |
| 67 |
vec_t r; |
vec_t r; |
| 68 |
face_t *f, *next; |
face_t *f, *next; |
| 69 |
winding_t *w; |
winding_t *w; |
| 70 |
plane_t *p, plane; |
plane_t clipplane, faceplane; |
| 71 |
mface_t *mf; |
mface_t *mf; |
| 72 |
vec3_t offset, point; |
vec3_t offset, point; |
| 73 |
|
|
| 76 |
|
|
| 77 |
brush_faces = NULL; |
brush_faces = NULL; |
| 78 |
|
|
| 79 |
rotate = !strncmp(ValueForKey(CurrentEntity, "classname"), "rotate_", 7); |
if (!strncmp(ValueForKey(CurrentEntity, "classname"), "rotate_", 7)) |
|
if (rotate) |
|
| 80 |
{ |
{ |
| 81 |
entity_t *FoundEntity; |
entity_t *FoundEntity; |
| 82 |
char *searchstring; |
char *searchstring; |
| 92 |
} |
} |
| 93 |
|
|
| 94 |
GetVectorForKey(CurrentEntity, "origin", offset); |
GetVectorForKey(CurrentEntity, "origin", offset); |
| 95 |
|
//printf("%i brushfaces at offset %f %f %f\n", numbrushfaces, offset[0], offset[1], offset[2]); |
| 96 |
|
|
| 97 |
for (i = 0;i < numbrushfaces;i++) |
for (i = 0;i < numbrushfaces;i++) |
| 98 |
{ |
{ |
| 99 |
mf = &faces[i]; |
mf = &faces[i]; |
|
VectorNegate( mf->plane.normal, point ); |
|
| 100 |
|
|
| 101 |
w = BaseWindingForPlane (&mf->plane); |
//printf("plane %f %f %f %f\n", mf->plane.normal[0], mf->plane.normal[1], mf->plane.normal[2], mf->plane.dist); |
| 102 |
|
faceplane = mf->plane; |
| 103 |
|
w = BaseWindingForPlane (&faceplane); |
| 104 |
|
|
| 105 |
|
//VectorNegate( faceplane.normal, point ); |
| 106 |
for (j = 0;j < numbrushfaces && w;j++) |
for (j = 0;j < numbrushfaces && w;j++) |
| 107 |
{ |
{ |
| 108 |
p = &faces[i].plane; |
clipplane = faces[j].plane; |
| 109 |
if( j == i/* || VectorCompare( p->normal, point )*/ ) |
if( j == i/* || VectorCompare( clipplane.normal, point )*/ ) |
| 110 |
continue; |
continue; |
| 111 |
|
|
| 112 |
// flip the plane, because we want to keep the back side |
// flip the plane, because we want to keep the back side |
| 113 |
VectorNegate(faces[j].plane.normal, plane.normal); |
VectorNegate(clipplane.normal, clipplane.normal); |
| 114 |
plane.dist = -faces[j].plane.dist; |
clipplane.dist *= -1; |
| 115 |
|
|
| 116 |
w = ClipWindingEpsilon (w, &plane, ON_EPSILON, true); |
w = ClipWindingEpsilon (w, &clipplane, ON_EPSILON, true); |
| 117 |
} |
} |
| 118 |
|
|
| 119 |
if (!w) |
if (!w) |
| 120 |
|
{ |
| 121 |
|
//printf("----- skipped plane -----\n"); |
| 122 |
continue; // overcontrained plane |
continue; // overcontrained plane |
| 123 |
|
} |
| 124 |
|
|
| 125 |
// this face is a keeper |
// this face is a keeper |
| 126 |
f = AllocFace (); |
f = AllocFace (); |
| 152 |
FreeFace (f); |
FreeFace (f); |
| 153 |
} |
} |
| 154 |
brush_faces = NULL; |
brush_faces = NULL; |
| 155 |
|
//printf("----- skipped brush -----\n"); |
| 156 |
return; |
return; |
| 157 |
} |
} |
| 158 |
|
|
| 161 |
|
|
| 162 |
CheckWinding( w ); |
CheckWinding( w ); |
| 163 |
|
|
| 164 |
VectorCopy (mf->plane.normal, plane.normal); |
faceplane.dist -= DotProduct(faceplane.normal, offset); |
|
VectorScale (mf->plane.normal, mf->plane.dist, point); |
|
|
VectorSubtract (point, offset, point); |
|
|
plane.dist = DotProduct (plane.normal, point); |
|
|
|
|
| 165 |
f->texturenum = mf->texinfo; |
f->texturenum = mf->texinfo; |
| 166 |
f->planenum = FindPlane (&plane, &f->planeside); |
f->planenum = FindPlane (&faceplane, &f->planeside); |
| 167 |
f->next = brush_faces; |
f->next = brush_faces; |
| 168 |
brush_faces = f; |
brush_faces = f; |
| 169 |
} |
} |
| 170 |
|
|
| 171 |
// Rotatable objects have to have a bounding box big enough |
// Rotatable objects have to have a bounding box big enough |
| 172 |
// to account for all its rotations. |
// to account for all its rotations. |
| 173 |
if (rotate) |
if (DotProduct(offset, offset)) |
| 174 |
{ |
{ |
| 175 |
vec_t delta; |
vec_t delta; |
| 176 |
|
|
| 182 |
brush_maxs[k] = delta; |
brush_maxs[k] = delta; |
| 183 |
} |
} |
| 184 |
} |
} |
|
} |
|
|
|
|
| 185 |
|
|
| 186 |
|
//printf("%i : %f %f %f : %f %f %f\n", numbrushfaces, brush_mins[0], brush_mins[1], brush_mins[2], brush_maxs[0], brush_maxs[1], brush_maxs[2]); |
| 187 |
|
} |
| 188 |
|
|
| 189 |
/* |
/* |
| 190 |
============================================================================== |
============================================================================== |
| 413 |
{ |
{ |
| 414 |
int i, x, s; |
int i, x, s; |
| 415 |
vec3_t corner; |
vec3_t corner; |
|
face_t *f; |
|
| 416 |
winding_t *w; |
winding_t *w; |
| 417 |
plane_t plane, *p; |
plane_t plane; |
| 418 |
|
|
| 419 |
|
int j, k, numwindings; |
| 420 |
|
vec_t r; |
| 421 |
|
winding_t **windings; |
| 422 |
|
plane_t clipplane, faceplane; |
| 423 |
|
mface_t *mf; |
| 424 |
|
vec3_t point; |
| 425 |
|
vec3_t mins, maxs; |
| 426 |
|
|
| 427 |
|
if (!numbrushfaces) |
| 428 |
|
return; |
| 429 |
|
|
| 430 |
num_hull_points = 0; |
num_hull_points = 0; |
| 431 |
num_hull_edges = 0; |
num_hull_edges = 0; |
| 432 |
|
|
| 433 |
// create all the hull points |
ClearBounds( mins, maxs ); |
| 434 |
for (f=brush_faces ; f ; f=f->next) |
|
| 435 |
|
// generate windings and bounds data |
| 436 |
|
numwindings = 0; |
| 437 |
|
windings = calloc(numbrushfaces, sizeof(*windings)); |
| 438 |
|
for (i = 0;i < numbrushfaces;i++) |
| 439 |
|
{ |
| 440 |
|
mf = &faces[i]; |
| 441 |
|
windings[i] = NULL; |
| 442 |
|
|
| 443 |
|
faceplane = mf->plane; |
| 444 |
|
w = BaseWindingForPlane (&faceplane); |
| 445 |
|
|
| 446 |
|
for (j = 0;j < numbrushfaces && w;j++) |
| 447 |
|
{ |
| 448 |
|
clipplane = faces[j].plane; |
| 449 |
|
if( j == i ) |
| 450 |
|
continue; |
| 451 |
|
|
| 452 |
|
// flip the plane, because we want to keep the back side |
| 453 |
|
VectorNegate(clipplane.normal, clipplane.normal); |
| 454 |
|
clipplane.dist *= -1; |
| 455 |
|
|
| 456 |
|
w = ClipWindingEpsilon (w, &clipplane, ON_EPSILON, true); |
| 457 |
|
} |
| 458 |
|
|
| 459 |
|
if (!w) |
| 460 |
|
continue; // overcontrained plane |
| 461 |
|
|
| 462 |
|
for (j = 0;j < w->numpoints;j++) |
| 463 |
|
{ |
| 464 |
|
for (k = 0;k < 3;k++) |
| 465 |
|
{ |
| 466 |
|
point[k] = w->points[j][k]; |
| 467 |
|
r = Q_rint( point[k] ); |
| 468 |
|
if ( fabs( point[k] - r ) < ZERO_EPSILON) |
| 469 |
|
w->points[j][k] = r; |
| 470 |
|
else |
| 471 |
|
w->points[j][k] = point[k]; |
| 472 |
|
|
| 473 |
|
// check for incomplete brushes |
| 474 |
|
if( w->points[j][k] >= BOGUS_RANGE || w->points[j][k] <= -BOGUS_RANGE ) |
| 475 |
|
return; |
| 476 |
|
} |
| 477 |
|
|
| 478 |
|
AddPointToBounds( w->points[j], mins, maxs ); |
| 479 |
|
} |
| 480 |
|
|
| 481 |
|
windings[i] = w; |
| 482 |
|
} |
| 483 |
|
|
| 484 |
|
// add all of the corner offsets |
| 485 |
|
for (i = 0;i < numwindings;i++) |
| 486 |
{ |
{ |
| 487 |
w = f->winding; |
w = windings[i]; |
| 488 |
for (i=0 ; i<w->numpoints ; i++) |
for (j = 0;j < w->numpoints;j++) |
| 489 |
AddHullPoint (w->points[i], hullnum); |
AddHullPoint(w->points[j], hullnum); |
| 490 |
} |
} |
| 491 |
|
|
| 492 |
// expand all of the planes |
// expand the face planes |
| 493 |
for (i=0 ; i<numbrushfaces ; i++) |
for (i=0 ; i<numbrushfaces ; i++) |
| 494 |
{ |
{ |
| 495 |
p = &faces[i].plane; |
mf = &faces[i]; |
|
VectorClear (corner); |
|
| 496 |
for (x=0 ; x<3 ; x++) |
for (x=0 ; x<3 ; x++) |
| 497 |
{ |
{ |
| 498 |
if (p->normal[x] > 0) |
if (mf->plane.normal[x] > 0) |
| 499 |
corner[x] = -hullinfo.hullsizes[hullnum][0][x]; |
corner[x] = -hullinfo.hullsizes[hullnum][0][x]; |
| 500 |
else if (p->normal[x] < 0) |
else if (mf->plane.normal[x] < 0) |
| 501 |
corner[x] = -hullinfo.hullsizes[hullnum][1][x]; |
corner[x] = -hullinfo.hullsizes[hullnum][1][x]; |
| 502 |
} |
} |
| 503 |
p->dist += DotProduct (corner, p->normal); |
mf->plane.dist += DotProduct (corner, mf->plane.normal); |
| 504 |
} |
} |
| 505 |
|
|
| 506 |
// add any axis planes not contained in the brush to bevel off corners |
// add any axis planes not contained in the brush to bevel off corners |
| 511 |
VectorClear (plane.normal); |
VectorClear (plane.normal); |
| 512 |
plane.normal[x] = s; |
plane.normal[x] = s; |
| 513 |
if (s == -1) |
if (s == -1) |
| 514 |
plane.dist = -brush_mins[x] + hullinfo.hullsizes[hullnum][1][x]; |
plane.dist = -mins[x] + hullinfo.hullsizes[hullnum][1][x]; |
| 515 |
else |
else |
| 516 |
plane.dist = brush_maxs[x] + -hullinfo.hullsizes[hullnum][0][x]; |
plane.dist = maxs[x] + -hullinfo.hullsizes[hullnum][0][x]; |
| 517 |
AddBrushPlane (&plane); |
AddBrushPlane (&plane); |
| 518 |
} |
} |
| 519 |
|
|
| 520 |
// add all of the edge bevels |
// add all of the edge bevels |
| 521 |
for (f=brush_faces ; f ; f=f->next) { |
for (i = 0;i < numwindings;i++) |
| 522 |
w = f->winding; |
{ |
| 523 |
for (i=0 ; i<w->numpoints ; i++) |
w = windings[i]; |
| 524 |
AddHullEdge (w->points[i], w->points[(i+1)%w->numpoints], hullnum); |
for (j = 0;j < w->numpoints;j++) |
| 525 |
|
AddHullEdge(w->points[j], w->points[(j+1)%w->numpoints], hullnum); |
| 526 |
} |
} |
| 527 |
|
|
| 528 |
|
// free the windings as we no longer need them |
| 529 |
|
for (i = 0;i < numwindings;i++) |
| 530 |
|
if (windings[i]) |
| 531 |
|
FreeWinding(windings[i]); |
| 532 |
|
free(windings); |
| 533 |
} |
} |
| 534 |
|
|
| 535 |
//============================================================================ |
//============================================================================ |
| 548 |
int contents; |
int contents; |
| 549 |
char *name; |
char *name; |
| 550 |
mface_t *f; |
mface_t *f; |
|
face_t *face, *next; |
|
| 551 |
|
|
| 552 |
// |
// |
| 553 |
// check texture name for attributes |
// check texture name for attributes |
| 609 |
numbrushfaces++; |
numbrushfaces++; |
| 610 |
} |
} |
| 611 |
|
|
| 612 |
|
if (hullnum) |
| 613 |
|
ExpandBrush (hullnum); |
| 614 |
|
|
| 615 |
CreateBrushFaces (); |
CreateBrushFaces (); |
| 616 |
|
|
| 617 |
if (!brush_faces) |
if (!brush_faces) |
| 620 |
return NULL; |
return NULL; |
| 621 |
} |
} |
| 622 |
|
|
|
if (hullnum) |
|
|
{ |
|
|
ExpandBrush (hullnum); |
|
|
for (face=brush_faces ; face ; face=next) |
|
|
{ |
|
|
next = face->next; |
|
|
FreeFace( face ); |
|
|
} |
|
|
CreateBrushFaces (); |
|
|
} |
|
|
|
|
| 623 |
// |
// |
| 624 |
// create the brush |
// create the brush |
| 625 |
// |
// |
| 629 |
VectorCopy (brush_mins, b->mins); |
VectorCopy (brush_mins, b->mins); |
| 630 |
VectorCopy (brush_maxs, b->maxs); |
VectorCopy (brush_maxs, b->maxs); |
| 631 |
// debugging code |
// debugging code |
| 632 |
//printf("brush\n"); |
//printf("mapbrush\n"); |
| 633 |
//for (f=mb->faces ; f ; f=f->next) |
//for (f=mb->faces ; f ; f=f->next) |
| 634 |
// printf("face %f %f %f %f \"%s\"\n", f->plane.normal[0], f->plane.normal[1], f->plane.normal[2], f->plane.dist, miptex[texinfo[f->texinfo].miptex]); |
// printf("face %f %f %f %f \"%s\"\n", f->plane.normal[0], f->plane.normal[1], f->plane.normal[2], f->plane.dist, miptex[texinfo[f->texinfo].miptex]); |
| 635 |
|
//printf("bspbrush %i\n", numbrushfaces); |
| 636 |
|
//face_t *face; |
| 637 |
|
//for (face=b->faces ; face ; face=face->next) |
| 638 |
|
// printf("bspface %f %f %f %f\n", mapplanes[face->planenum].normal[0], mapplanes[face->planenum].normal[1], mapplanes[face->planenum].normal[2], mapplanes[face->planenum].dist); |
| 639 |
|
|
| 640 |
return b; |
return b; |
| 641 |
} |
} |