00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "stdafx.h"
00024 #include "qe3.h"
00025 #include "winding.h"
00026
00027
00028
00029
00030
00031
00032
00033
00034 void Brush_Scale(brush_t* b)
00035 {
00036 for (face_t* f = b->brush_faces ; f ; f=f->next)
00037 {
00038 for (int i=0 ; i<3 ; i++)
00039 {
00040 VectorScale (f->planepts[i], g_qeglobals.d_gridsize, f->planepts[i]);
00041 }
00042 }
00043 }
00044
00045 void CSG_MakeHollow (void)
00046 {
00047 brush_t *b, *front, *back, *next;
00048 face_t *f;
00049 face_t split;
00050 vec3_t move;
00051 int i;
00052
00053 for (b = selected_brushes.next ; b != &selected_brushes ; b=next)
00054 {
00055 next = b->next;
00056
00057 if (b->owner->eclass->fixedsize || b->patchBrush || b->terrainBrush || b->hiddenBrush)
00058 continue;
00059
00060 for (f = b->brush_faces ; f ; f=f->next)
00061 {
00062 split = *f;
00063 VectorScale (f->plane.normal, g_qeglobals.d_gridsize, move);
00064 for (i=0 ; i<3 ; i++)
00065 VectorSubtract (split.planepts[i], move, split.planepts[i]);
00066
00067 Brush_SplitBrushByFace (b, &split, &front, &back);
00068 if (back)
00069 Brush_Free (back);
00070 if (front)
00071 Brush_AddToList (front, &selected_brushes);
00072 }
00073 Brush_Free (b);
00074 }
00075 Sys_UpdateWindows (W_ALL);
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 brush_t *Brush_Merge(brush_t *brush1, brush_t *brush2, int onlyshape)
00092 {
00093 int i, shared;
00094 brush_t *newbrush;
00095 face_t *face1, *face2, *newface, *f;
00096
00097
00098 for (i = 0; i < 3; i++)
00099 {
00100 if (brush1->mins[i] > brush2->maxs[i] + ON_EPSILON
00101 || brush1->maxs[i] < brush2->mins[i] - ON_EPSILON)
00102 {
00103
00104 return NULL;
00105 }
00106 }
00107
00108 shared = 0;
00109
00110 for (face1 = brush1->brush_faces; face1; face1 = face1->next)
00111 {
00112
00113 for (face2 = brush2->brush_faces; face2; face2 = face2->next)
00114 {
00115 if (Plane_Equal(&face1->plane, &face2->plane, true))
00116 {
00117 shared++;
00118
00119 if (shared > 1)
00120 return NULL;
00121 break;
00122 }
00123 }
00124
00125 if (face2) continue;
00126
00127 for (face2 = brush2->brush_faces; face2; face2 = face2->next)
00128 {
00129
00130 for (f = brush1->brush_faces; f; f = f->next)
00131 {
00132 if (Plane_Equal(&face2->plane, &f->plane, true)) break;
00133 }
00134 if (f)
00135 continue;
00136
00137 if (Plane_Equal(&face1->plane, &face2->plane, false))
00138 {
00139
00140 if (!onlyshape && stricmp(face1->texdef.name, face2->texdef.name) != 0) return NULL;
00141 continue;
00142 }
00143
00144 if (Winding_PlanesConcave(face1->face_winding, face2->face_winding,
00145 face1->plane.normal, face2->plane.normal,
00146 face1->plane.dist, face2->plane.dist))
00147 {
00148 return NULL;
00149 }
00150 }
00151 }
00152
00153 newbrush = Brush_Alloc();
00154
00155 for (face1 = brush1->brush_faces; face1; face1 = face1->next)
00156 {
00157
00158 for (face2 = brush2->brush_faces; face2; face2 = face2->next)
00159 {
00160 if (Plane_Equal(&face1->plane, &face2->plane, true))
00161 break;
00162 }
00163 if (face2)
00164 continue;
00165
00166 for (f = newbrush->brush_faces; f; f = f->next)
00167 {
00168 if (Plane_Equal(&face1->plane, &f->plane, false))
00169 break;
00170 if (Plane_Equal(&face1->plane, &f->plane, true))
00171 break;
00172 }
00173 if (f)
00174 continue;
00175
00176 newface = Face_Alloc();
00177 newface->texdef = face1->texdef;
00178 VectorCopy(face1->planepts[0], newface->planepts[0]);
00179 VectorCopy(face1->planepts[1], newface->planepts[1]);
00180 VectorCopy(face1->planepts[2], newface->planepts[2]);
00181 newface->plane = face1->plane;
00182 newface->next = newbrush->brush_faces;
00183 newbrush->brush_faces = newface;
00184 }
00185
00186 for (face2 = brush2->brush_faces; face2; face2 = face2->next)
00187 {
00188
00189 for (face1 = brush1->brush_faces; face1; face1 = face1->next)
00190 {
00191 if (Plane_Equal(&face2->plane, &face1->plane, true))
00192 break;
00193 }
00194 if (face1)
00195 continue;
00196
00197 for (f = newbrush->brush_faces; f; f = f->next)
00198 {
00199 if (Plane_Equal(&face2->plane, &f->plane, false))
00200 break;
00201 if (Plane_Equal(&face2->plane, &f->plane, true))
00202 break;
00203 }
00204 if (f)
00205 continue;
00206
00207 newface = Face_Alloc();
00208 newface->texdef = face2->texdef;
00209 VectorCopy(face2->planepts[0], newface->planepts[0]);
00210 VectorCopy(face2->planepts[1], newface->planepts[1]);
00211 VectorCopy(face2->planepts[2], newface->planepts[2]);
00212 newface->plane = face2->plane;
00213 newface->next = newbrush->brush_faces;
00214 newbrush->brush_faces = newface;
00215 }
00216
00217 Entity_LinkBrush (brush1->owner, newbrush);
00218
00219 Brush_BuildWindings( newbrush, false);
00220 return newbrush;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 brush_t *Brush_MergeListPairs(brush_t *brushlist, int onlyshape)
00234 {
00235 int nummerges, merged;
00236 brush_t *b1, *b2, *tail, *newbrush, *newbrushlist;
00237 brush_t *lastb2;
00238
00239 if (!brushlist) return NULL;
00240
00241 nummerges = 0;
00242 do
00243 {
00244 for (tail = brushlist; tail; tail = tail->next)
00245 {
00246 if (!tail->next) break;
00247 }
00248 merged = 0;
00249 newbrushlist = NULL;
00250 for (b1 = brushlist; b1; b1 = brushlist)
00251 {
00252 lastb2 = b1;
00253 for (b2 = b1->next; b2; b2 = b2->next)
00254 {
00255 newbrush = Brush_Merge(b1, b2, onlyshape);
00256 if (newbrush)
00257 {
00258 tail->next = newbrush;
00259 lastb2->next = b2->next;
00260 brushlist = brushlist->next;
00261 b1->next = b1->prev = NULL;
00262 b2->next = b2->prev = NULL;
00263 Brush_Free(b1);
00264 Brush_Free(b2);
00265 for (tail = brushlist; tail; tail = tail->next)
00266 {
00267 if (!tail->next) break;
00268 }
00269 merged++;
00270 nummerges++;
00271 break;
00272 }
00273 lastb2 = b2;
00274 }
00275
00276 if (!b2)
00277 {
00278 brushlist = brushlist->next;
00279
00280 b1->next = newbrushlist;
00281 newbrushlist = b1;
00282 }
00283 }
00284 brushlist = newbrushlist;
00285 } while(merged);
00286 return newbrushlist;
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 brush_t *Brush_MergeList(brush_t *brushlist, int onlyshape)
00305 {
00306 brush_t *brush1, *brush2, *brush3, *newbrush;
00307 face_t *face1, *face2, *face3, *newface, *f;
00308
00309 if (!brushlist) return NULL;
00310 for (brush1 = brushlist; brush1; brush1 = brush1->next)
00311 {
00312
00313 for (face1 = brush1->brush_faces; face1; face1 = face1->next)
00314 {
00315
00316 for (brush2 = brushlist; brush2; brush2 = brush2->next)
00317 {
00318 if (brush2 == brush1) continue;
00319 for (face2 = brush2->brush_faces; face2; face2 = face2->next)
00320 {
00321 if (Plane_Equal(&face1->plane, &face2->plane, true))
00322 {
00323 break;
00324 }
00325 }
00326 if (face2) break;
00327 }
00328
00329 if (brush2) continue;
00330
00331 for (brush2 = brush1->next; brush2; brush2 = brush2->next)
00332 {
00333
00334 for (face2 = brush2->brush_faces; face2; face2 = face2->next)
00335 {
00336 for (brush3 = brushlist; brush3; brush3 = brush3->next)
00337 {
00338 if (brush3 == brush2) continue;
00339 for (face3 = brush3->brush_faces; face3; face3 = face3->next)
00340 {
00341 if (Plane_Equal(&face2->plane, &face3->plane, true)) break;
00342 }
00343 if (face3) break;
00344 }
00345
00346 if (brush3) continue;
00347
00348 if (Plane_Equal(&face1->plane, &face2->plane, false))
00349 {
00350
00351 if (!onlyshape && stricmp(face1->texdef.name, face2->texdef.name) != 0) return NULL;
00352 continue;
00353 }
00354
00355 if (Winding_PlanesConcave(face1->face_winding, face2->face_winding,
00356 face1->plane.normal, face2->plane.normal,
00357 face1->plane.dist, face2->plane.dist))
00358 {
00359 return NULL;
00360 }
00361 }
00362 }
00363 }
00364 }
00365
00366 newbrush = Brush_Alloc();
00367
00368 for (brush1 = brushlist; brush1; brush1 = brush1->next)
00369 {
00370 for (face1 = brush1->brush_faces; face1; face1 = face1->next)
00371 {
00372
00373 for (brush2 = brushlist; brush2; brush2 = brush2->next)
00374 {
00375 if (brush2 == brush1) continue;
00376 for (face2 = brush2->brush_faces; face2; face2 = face2->next)
00377 {
00378 if (Plane_Equal(&face1->plane, &face2->plane, true))
00379 {
00380 break;
00381 }
00382 }
00383 if (face2) break;
00384 }
00385 if (brush2) continue;
00386
00387 for (f = newbrush->brush_faces; f; f = f->next)
00388 {
00389 if (Plane_Equal(&face1->plane, &f->plane, false))
00390 break;
00391 if (Plane_Equal(&face1->plane, &f->plane, true))
00392 break;
00393 }
00394 if (f)
00395 continue;
00396
00397 newface = Face_Alloc();
00398 newface->texdef = face1->texdef;
00399 VectorCopy(face1->planepts[0], newface->planepts[0]);
00400 VectorCopy(face1->planepts[1], newface->planepts[1]);
00401 VectorCopy(face1->planepts[2], newface->planepts[2]);
00402 newface->plane = face1->plane;
00403 newface->next = newbrush->brush_faces;
00404 newbrush->brush_faces = newface;
00405 }
00406 }
00407
00408 Entity_LinkBrush (brushlist->owner, newbrush);
00409
00410 Brush_BuildWindings( newbrush, false);
00411 return newbrush;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 brush_t *Brush_Subtract(brush_t *a, brush_t *b)
00424 {
00425
00426 brush_t *front, *back;
00427 brush_t *in, *out, *next;
00428 face_t *f;
00429
00430 in = a;
00431 out = NULL;
00432 for (f = b->brush_faces; f && in; f = f->next)
00433 {
00434 Brush_SplitBrushByFace(in, f, &front, &back);
00435 if (in != a) Brush_Free(in);
00436 if (front)
00437 {
00438 front->next = out;
00439 out = front;
00440 }
00441 in = back;
00442 }
00443
00444 if (in && in != a)
00445 {
00446 Brush_Free(in);
00447 }
00448 else
00449 {
00450 for (b = out; b; b = next)
00451 {
00452 next = b->next;
00453 b->next = b->prev = NULL;
00454 Brush_Free(b);
00455 }
00456 return a;
00457 }
00458 return out;
00459 }
00460
00461
00462
00463
00464
00465
00466 void CSG_Subtract (void)
00467 {
00468 brush_t *b, *s, *fragments, *nextfragment, *frag, *next, *snext;
00469 brush_t fragmentlist;
00470 int i, numfragments, numbrushes;
00471
00472 Sys_Printf ("Subtracting...\n");
00473
00474 if (selected_brushes.next == &selected_brushes)
00475 {
00476 Sys_Printf("No brushes selected.\n");
00477 return;
00478 }
00479
00480 fragmentlist.next = &fragmentlist;
00481 fragmentlist.prev = &fragmentlist;
00482
00483 numfragments = 0;
00484 numbrushes = 0;
00485 for (b = selected_brushes.next ; b != &selected_brushes ; b=next)
00486 {
00487 next = b->next;
00488
00489 if (b->owner->eclass->fixedsize)
00490 continue;
00491
00492
00493 for (s = fragmentlist.next; s != &fragmentlist; s = snext)
00494 {
00495 snext = s->next;
00496
00497 for (i=0 ; i<3 ; i++)
00498 if (b->mins[i] >= s->maxs[i] - ON_EPSILON
00499 || b->maxs[i] <= s->mins[i] + ON_EPSILON)
00500 break;
00501 if (i != 3)
00502 continue;
00503 fragments = Brush_Subtract(s, b);
00504
00505 if (fragments == s)
00506 continue;
00507
00508 fragments = Brush_MergeListPairs(fragments, true);
00509
00510 for (frag = fragments; frag; frag = nextfragment)
00511 {
00512 nextfragment = frag->next;
00513 frag->next = NULL;
00514 frag->owner = s->owner;
00515 Brush_AddToList(frag, &fragmentlist);
00516 }
00517
00518 Brush_Free(s);
00519 }
00520
00521
00522 for (s = active_brushes.next; s != &active_brushes; s = snext)
00523 {
00524 snext = s->next;
00525
00526 if (s->owner->eclass->fixedsize || s->patchBrush || s->terrainBrush || s->hiddenBrush)
00527 continue;
00528
00529
00530 if (s->brush_faces->d_texture->bFromShader && (s->brush_faces->d_texture->nShaderFlags & QER_NOCARVE))
00531 {
00532 continue;
00533 }
00534
00535 for (i=0 ; i<3 ; i++)
00536 if (b->mins[i] >= s->maxs[i] - ON_EPSILON
00537 || b->maxs[i] <= s->mins[i] + ON_EPSILON)
00538 break;
00539 if (i != 3)
00540 continue;
00541
00542 fragments = Brush_Subtract(s, b);
00543
00544 if (fragments == s)
00545 continue;
00546
00547 Undo_AddBrush(s);
00548
00549 numbrushes++;
00550
00551 fragments = Brush_MergeListPairs(fragments, true);
00552
00553 for (frag = fragments; frag; frag = nextfragment)
00554 {
00555 nextfragment = frag->next;
00556 frag->next = NULL;
00557 frag->owner = s->owner;
00558 Brush_AddToList(frag, &fragmentlist);
00559 }
00560
00561 Brush_Free(s);
00562 }
00563 }
00564
00565
00566 for (frag = fragmentlist.next; frag != &fragmentlist; frag = nextfragment)
00567 {
00568 nextfragment = frag->next;
00569 numfragments++;
00570 Brush_RemoveFromList(frag);
00571 Brush_AddToList(frag, &active_brushes);
00572 Undo_EndBrush(frag);
00573 }
00574
00575 if (numfragments == 0)
00576 {
00577 Sys_Printf("Selected brush%s did not intersect with any other brushes.\n",
00578 (selected_brushes.next->next == &selected_brushes) ? "":"es");
00579 return;
00580 }
00581 Sys_Printf("done. (created %d fragment%s out of %d brush%s)\n", numfragments, (numfragments == 1)?"":"s",
00582 numbrushes, (numbrushes == 1)?"":"es");
00583 Sys_UpdateWindows(W_ALL);
00584 }
00585
00586
00587
00588
00589
00590
00591 void CSG_Merge(void)
00592 {
00593 brush_t *b, *next, *newlist, *newbrush;
00594 struct entity_s *owner;
00595
00596 Sys_Printf ("Merging...\n");
00597
00598 if (selected_brushes.next == &selected_brushes)
00599 {
00600 Sys_Printf("No brushes selected.\n");
00601 return;
00602 }
00603
00604 if (selected_brushes.next->next == &selected_brushes)
00605 {
00606 Sys_Printf("At least two brushes have to be selected.\n");
00607 return;
00608 }
00609
00610 owner = selected_brushes.next->owner;
00611
00612 for (b = selected_brushes.next; b != &selected_brushes; b = next)
00613 {
00614 next = b->next;
00615
00616 if (b->owner->eclass->fixedsize)
00617 {
00618
00619 Sys_Printf("Cannot add fixed size entities.\n");
00620 return;
00621 }
00622
00623 if (b->patchBrush)
00624 {
00625 Sys_Printf("Cannot add patches.\n");
00626 return;
00627 }
00628 if (b->terrainBrush)
00629 {
00630 Sys_Printf("Cannot add terrains.\n");
00631 return;
00632 }
00633
00634 if (b->brush_faces->d_texture->bFromShader && (b->brush_faces->d_texture->nShaderFlags & QER_NOCARVE))
00635 {
00636 Sys_Printf("Cannot add brushes using shaders that don't allows CSG operations.\n");
00637 return;
00638 }
00639
00640 if (b->owner != owner)
00641 {
00642 Sys_Printf("Cannot add brushes from different entities.\n");
00643 return;
00644 }
00645
00646 }
00647
00648 newlist = NULL;
00649 for (b = selected_brushes.next; b != &selected_brushes; b = next)
00650 {
00651 next = b->next;
00652
00653 Brush_RemoveFromList(b);
00654 b->next = newlist;
00655 b->prev = NULL;
00656 newlist = b;
00657 }
00658
00659 newbrush = Brush_MergeList(newlist, true);
00660
00661 if (!newbrush)
00662 {
00663
00664 for (b = newlist; b; b = next)
00665 {
00666 next = b->next;
00667 b->next = NULL;
00668 b->prev = NULL;
00669 Brush_AddToList(b, &selected_brushes);
00670 }
00671 Sys_Printf("Cannot add a set of brushes with a concave hull.\n");
00672 return;
00673 }
00674
00675 for (b = newlist; b; b = next)
00676 {
00677 next = b->next;
00678 b->next = NULL;
00679 b->prev = NULL;
00680 Brush_Free(b);
00681 }
00682 Brush_AddToList(newbrush, &selected_brushes);
00683
00684 Sys_Printf ("done.\n");
00685 Sys_UpdateWindows (W_ALL);
00686 }