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 "stdafx.h"
00025 #include <assert.h>
00026 #include "qe3.h"
00027 #include "winding.h"
00028
00029
00030
00031
00032 int g_nBrushId = 0;
00033
00034 const char* Brush_Name(brush_t *b)
00035 {
00036 static char cBuff[1024];
00037 b->numberId = g_nBrushId++;
00038 if (g_qeglobals.m_bBrushPrimitMode)
00039 {
00040 sprintf(cBuff, "Brush %i", b->numberId);
00041 Brush_SetEpair(b, "Name", cBuff);
00042 }
00043 return cBuff;
00044 }
00045
00046 brush_t *Brush_Alloc()
00047 {
00048 brush_t *b = (brush_t*)qmalloc(sizeof(brush_t));
00049 return b;
00050 }
00051
00052
00053
00054
00055 void PrintWinding (winding_t *w)
00056 {
00057 int i;
00058
00059 printf ("-------------\n");
00060 for (i=0 ; i<w->numpoints ; i++)
00061 printf ("(%5.2f, %5.2f, %5.2f)\n", w->points[i][0]
00062 , w->points[i][1], w->points[i][2]);
00063 }
00064
00065 void PrintPlane (plane_t *p)
00066 {
00067 printf ("(%5.2f, %5.2f, %5.2f) : %5.2f\n", p->normal[0], p->normal[1],
00068 p->normal[2], p->dist);
00069 }
00070
00071 void PrintVector (vec3_t v)
00072 {
00073 printf ("(%5.2f, %5.2f, %5.2f)\n", v[0], v[1], v[2]);
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 vec3_t baseaxis[18] =
00092 {
00093 {0,0,1}, {1,0,0}, {0,-1,0},
00094 {0,0,-1}, {1,0,0}, {0,-1,0},
00095 {1,0,0}, {0,1,0}, {0,0,-1},
00096 {-1,0,0}, {0,1,0}, {0,0,-1},
00097 {0,1,0}, {1,0,0}, {0,0,-1},
00098 {0,-1,0}, {1,0,0}, {0,0,-1}
00099 };
00100
00101 void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
00102 {
00103 int bestaxis;
00104 float dot,best;
00105 int i;
00106
00107 best = 0;
00108 bestaxis = 0;
00109
00110 for (i=0 ; i<6 ; i++)
00111 {
00112 dot = DotProduct (pln->normal, baseaxis[i*3]);
00113 if (dot > best)
00114 {
00115 best = dot;
00116 bestaxis = i;
00117 }
00118 }
00119
00120 VectorCopy (baseaxis[bestaxis*3+1], xv);
00121 VectorCopy (baseaxis[bestaxis*3+2], yv);
00122 }
00123
00124
00125
00126 float lightaxis[3] = {0.6, 0.8, 1.0};
00127
00128
00129
00130
00131
00132
00133
00134
00135 float SetShadeForPlane (plane_t *p)
00136 {
00137 int i;
00138 float f;
00139
00140
00141 for (i=0 ; i<3 ; i++)
00142 if (fabs(p->normal[i]) > 0.9)
00143 {
00144 f = lightaxis[i];
00145 return f;
00146 }
00147
00148
00149 for (i=0 ; i<3 ; i++)
00150 if (fabs(p->normal[i]) < 0.1)
00151 {
00152 f = (lightaxis[(i+1)%3] + lightaxis[(i+2)%3])/2;
00153 return f;
00154 }
00155
00156
00157 f= (lightaxis[0] + lightaxis[1] + lightaxis[2]) / 3;
00158 return f;
00159 }
00160
00161 vec3_t vecs[2];
00162 float shift[2];
00163
00164
00165
00166
00167
00168
00169 face_t *Face_Alloc( void )
00170 {
00171 face_t *f = (face_t*)qmalloc( sizeof( *f ) );
00172
00173 if (g_qeglobals.bSurfacePropertiesPlugin)
00174 f->pData = static_cast<void *>( g_SurfaceTable.m_pfnTexdefAlloc( f ) );
00175
00176 return f;
00177 }
00178
00179
00180
00181
00182
00183
00184 void Face_Free( face_t *f )
00185 {
00186 assert( f != 0 );
00187
00188 if ( f->face_winding )
00189 {
00190 free( f->face_winding );
00191 f->face_winding = 0;
00192 }
00193
00194 if (g_qeglobals.bSurfacePropertiesPlugin)
00195 {
00196 #ifdef _DEBUG
00197 if ( !f->pData )
00198 {
00199 Sys_Printf("WARNING: unexpected IPluginTexdef is NULL in Face_Free\n");
00200 }
00201 else
00202 #endif
00203 GETPLUGINTEXDEF(f)->DecRef();
00204 }
00205
00206 f->texdef.~texdef_t();;
00207
00208 free( f );
00209 }
00210
00211
00212
00213
00214
00215
00216 face_t *Face_Clone (face_t *f)
00217 {
00218 face_t *n;
00219
00220 n = Face_Alloc();
00221 n->texdef = f->texdef;
00222
00223 memcpy (n->planepts, f->planepts, sizeof(n->planepts));
00224
00225
00226 return n;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236 face_t *Face_FullClone (face_t *f)
00237 {
00238 face_t *n;
00239
00240 n = Face_Alloc();
00241 n->texdef = f->texdef;
00242 memcpy(n->planepts, f->planepts, sizeof(n->planepts));
00243 memcpy(&n->plane, &f->plane, sizeof(plane_t));
00244 if (f->face_winding)
00245 n->face_winding = Winding_Clone(f->face_winding);
00246 else
00247 n->face_winding = NULL;
00248 n->d_texture = Texture_ForName( n->texdef.name );
00249 return n;
00250 }
00251
00252
00253
00254
00255
00256
00257 void Clamp(float& f, int nClamp)
00258 {
00259 float fFrac = f - static_cast<int>(f);
00260 f = static_cast<int>(f) % nClamp;
00261 f += fFrac;
00262 }
00263
00264
00265
00266
00267
00268
00269 void Face_MoveTexture(face_t *f, vec3_t delta)
00270 {
00271 vec3_t vX, vY;
00272
00273
00274
00275
00276
00277
00278 if (g_qeglobals.m_bBrushPrimitMode)
00279 Face_MoveTexture_BrushPrimit( f, delta );
00280 else
00281 {
00282 TextureAxisFromPlane(&f->plane, vX, vY);
00283
00284 vec3_t vDP, vShift;
00285 vDP[0] = DotProduct(delta, vX);
00286 vDP[1] = DotProduct(delta, vY);
00287
00288 double fAngle = f->texdef.rotate / 180 * Q_PI;
00289 double c = cos(fAngle);
00290 double s = sin(fAngle);
00291
00292 vShift[0] = vDP[0] * c - vDP[1] * s;
00293 vShift[1] = vDP[0] * s + vDP[1] * c;
00294
00295 if (!f->texdef.scale[0])
00296 f->texdef.scale[0] = 1;
00297 if (!f->texdef.scale[1])
00298 f->texdef.scale[1] = 1;
00299
00300 f->texdef.shift[0] -= vShift[0] / f->texdef.scale[0];
00301 f->texdef.shift[1] -= vShift[1] / f->texdef.scale[1];
00302
00303
00304 Clamp(f->texdef.shift[0], f->d_texture->width);
00305 Clamp(f->texdef.shift[1], f->d_texture->height);
00306 }
00307 }
00308
00309
00310
00311
00312
00313
00314 void Face_SetColor (brush_t *b, face_t *f, float fCurveColor)
00315 {
00316 float shade;
00317 qtexture_t *q;
00318
00319 q = f->d_texture;
00320
00321
00322 shade = SetShadeForPlane (&f->plane);
00323 if (g_pParentWnd->GetCamera()->Camera().draw_mode == cd_texture && !b->owner->eclass->fixedsize)
00324 {
00325
00326
00327 f->d_color[0] =
00328 f->d_color[1] =
00329 f->d_color[2] = shade;
00330 }
00331 else
00332 {
00333 f->d_color[0] = shade*q->color[0];
00334 f->d_color[1] = shade*q->color[1];
00335 f->d_color[2] = shade*q->color[2];
00336 }
00337 }
00338
00339
00340
00341
00342
00343
00344
00345 void Face_TextureVectors (face_t *f, float STfromXYZ[2][4])
00346 {
00347 vec3_t pvecs[2];
00348 int sv, tv;
00349 float ang, sinv, cosv;
00350 float ns, nt;
00351 int i,j;
00352 qtexture_t *q;
00353 texdef_t *td;
00354
00355 #ifdef _DEBUG
00356
00357
00358 if (g_qeglobals.m_bBrushPrimitMode && !g_qeglobals.bNeedConvert)
00359 Sys_Printf("Warning : illegal call of Face_TextureVectors in brush primitive mode\n");
00360 #endif
00361
00362 td = &f->texdef;
00363 q = f->d_texture;
00364
00365 memset (STfromXYZ, 0, 8*sizeof(float));
00366
00367 if (!td->scale[0])
00368 td->scale[0] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
00369 if (!td->scale[1])
00370 td->scale[1] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
00371
00372
00373 TextureAxisFromPlane(&f->plane, pvecs[0], pvecs[1]);
00374
00375
00376 if (td->rotate == 0)
00377 { sinv = 0 ; cosv = 1; }
00378 else if (td->rotate == 90)
00379 { sinv = 1 ; cosv = 0; }
00380 else if (td->rotate == 180)
00381 { sinv = 0 ; cosv = -1; }
00382 else if (td->rotate == 270)
00383 { sinv = -1 ; cosv = 0; }
00384 else
00385 {
00386 ang = td->rotate / 180 * Q_PI;
00387 sinv = sin(ang);
00388 cosv = cos(ang);
00389 }
00390
00391 if (pvecs[0][0])
00392 sv = 0;
00393 else if (pvecs[0][1])
00394 sv = 1;
00395 else
00396 sv = 2;
00397
00398 if (pvecs[1][0])
00399 tv = 0;
00400 else if (pvecs[1][1])
00401 tv = 1;
00402 else
00403 tv = 2;
00404
00405 for (i=0 ; i<2 ; i++) {
00406 ns = cosv * pvecs[i][sv] - sinv * pvecs[i][tv];
00407 nt = sinv * pvecs[i][sv] + cosv * pvecs[i][tv];
00408 STfromXYZ[i][sv] = ns;
00409 STfromXYZ[i][tv] = nt;
00410 }
00411
00412
00413 for (i=0 ; i<2 ; i++)
00414 for (j=0 ; j<3 ; j++)
00415 STfromXYZ[i][j] = STfromXYZ[i][j] / td->scale[i];
00416
00417
00418 STfromXYZ[0][3] = td->shift[0];
00419 STfromXYZ[1][3] = td->shift[1];
00420
00421 for (j=0 ; j<4 ; j++) {
00422 STfromXYZ[0][j] /= q->width;
00423 STfromXYZ[1][j] /= q->height;
00424 }
00425 }
00426
00427
00428
00429
00430
00431
00432 void Face_MakePlane (face_t *f)
00433 {
00434 int j;
00435 vec3_t t1, t2, t3;
00436
00437
00438 for (j=0 ; j<3 ; j++)
00439 {
00440 t1[j] = f->planepts[0][j] - f->planepts[1][j];
00441 t2[j] = f->planepts[2][j] - f->planepts[1][j];
00442 t3[j] = f->planepts[1][j];
00443 }
00444
00445 CrossProduct(t1,t2, f->plane.normal);
00446 if (VectorCompare (f->plane.normal, vec3_origin))
00447 printf ("WARNING: brush plane with no normal\n");
00448 VectorNormalize (f->plane.normal);
00449 f->plane.dist = DotProduct (t3, f->plane.normal);
00450 }
00451
00452
00453
00454
00455
00456
00457 void EmitTextureCoordinates ( float *xyzst, qtexture_t *q, face_t *f)
00458 {
00459 float STfromXYZ[2][4];
00460
00461 Face_TextureVectors (f, STfromXYZ);
00462 xyzst[3] = DotProduct (xyzst, STfromXYZ[0]) + STfromXYZ[0][3];
00463 xyzst[4] = DotProduct (xyzst, STfromXYZ[1]) + STfromXYZ[1][3];
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473 void Brush_MakeFacePlanes (brush_t *b)
00474 {
00475 face_t *f;
00476
00477 for (f=b->brush_faces ; f ; f=f->next)
00478 {
00479 Face_MakePlane (f);
00480 }
00481 }
00482
00483
00484
00485
00486
00487
00488 void DrawBrushEntityName (brush_t *b)
00489 {
00490 char *name;
00491
00492
00493
00494
00495 if (!b->owner)
00496 return;
00497
00498 if (b->owner == world_entity)
00499 return;
00500
00501 if (b != b->owner->brushes.onext)
00502 return;
00503
00504
00505 #if 0
00506 if (!(g_qeglobals.d_savedinfo.exclude & EXCLUDE_ANGLES))
00507 {
00508
00509 a = FloatForKey (b->owner, "angle");
00510 if (a)
00511 {
00512 s = sin (a/180*Q_PI);
00513 c = cos (a/180*Q_PI);
00514 for (i=0 ; i<3 ; i++)
00515 mid[i] = (b->mins[i] + b->maxs[i])*0.5;
00516
00517 qglBegin (GL_LINE_STRIP);
00518 qglVertex3fv (mid);
00519 mid[0] += c*8;
00520 mid[1] += s*8;
00521 mid[2] += s*8;
00522 qglVertex3fv (mid);
00523 mid[0] -= c*4;
00524 mid[1] -= s*4;
00525 mid[2] -= s*4;
00526 mid[0] -= s*4;
00527 mid[1] += c*4;
00528 mid[2] += c*4;
00529 qglVertex3fv (mid);
00530 mid[0] += c*4;
00531 mid[1] += s*4;
00532 mid[2] += s*4;
00533 mid[0] += s*4;
00534 mid[1] -= c*4;
00535 mid[2] -= c*4;
00536 qglVertex3fv (mid);
00537 mid[0] -= c*4;
00538 mid[1] -= s*4;
00539 mid[2] -= s*4;
00540 mid[0] += s*4;
00541 mid[1] -= c*4;
00542 mid[2] -= c*4;
00543 qglVertex3fv (mid);
00544 qglEnd ();
00545 }
00546 }
00547 #endif
00548
00549 if (g_qeglobals.d_savedinfo.show_names)
00550 {
00551 name = ValueForKey (b->owner, "classname");
00552 qglRasterPos3f (b->mins[0]+4, b->mins[1]+4, b->mins[2]+4);
00553 qglCallLists (strlen(name), GL_UNSIGNED_BYTE, name);
00554 }
00555 }
00556
00557
00558
00559
00560
00561
00562
00563
00564 winding_t *Brush_MakeFaceWinding (brush_t *b, face_t *face)
00565 {
00566 winding_t *w;
00567 face_t *clip;
00568 plane_t plane;
00569 qboolean past;
00570
00571
00572 w = Winding_BaseForPlane (&face->plane);
00573
00574
00575 past = false;
00576 for (clip = b->brush_faces ; clip && w ; clip=clip->next)
00577 {
00578 if (clip == face)
00579 {
00580 past = true;
00581 continue;
00582 }
00583 if (DotProduct (face->plane.normal, clip->plane.normal) > 0.999
00584 && fabs(face->plane.dist - clip->plane.dist) < 0.01 )
00585 {
00586 if (past)
00587 {
00588 free (w);
00589 return NULL;
00590 }
00591 continue;
00592 }
00593
00594
00595 VectorSubtract (vec3_origin,clip->plane.normal, plane.normal);
00596 plane.dist = -clip->plane.dist;
00597
00598 w = Winding_Clip (w, &plane, false);
00599 if (!w)
00600 return w;
00601 }
00602
00603 if (w->numpoints < 3)
00604 {
00605 free(w);
00606 w = NULL;
00607 }
00608
00609 if (!w)
00610 printf ("unused plane\n");
00611
00612 return w;
00613 }
00614
00615
00616
00617
00618
00619
00620 void Brush_SnapPlanepts (brush_t *b)
00621 {
00622 int i, j;
00623 face_t *f;
00624
00625 if (g_PrefsDlg.m_bNoClamp)
00626 return;
00627
00628 for (f=b->brush_faces ; f; f=f->next)
00629 for (i=0 ; i<3 ; i++)
00630 for (j=0 ; j<3 ; j++)
00631 f->planepts[i][j] = floor (f->planepts[i][j] + 0.5);
00632 }
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643 void Brush_Build( brush_t *b, bool bSnap, bool bMarkMap, bool bConvert )
00644 {
00645 bool bLocalConvert;
00646
00647 #ifdef _DEBUG
00648 if (!g_qeglobals.m_bBrushPrimitMode && bConvert)
00649 Sys_Printf("Warning : conversion from brush primitive to old brush format not implemented\n");
00650 #endif
00651
00652
00653 if (bConvert && !g_qeglobals.bNeedConvert)
00654 {
00655 bLocalConvert = true;
00656 g_qeglobals.bNeedConvert = true;
00657 }
00658
00659
00660
00661
00662 Brush_BuildWindings(b, bSnap);
00663
00664 Patch_BuildPoints (b);
00665
00666
00667
00668
00669 if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_edge)
00670 SetupVertexSelection ();
00671
00672 if (b->itemOwner == NULL)
00673 Group_AddToProperGroup(b);
00674
00675 if (bMarkMap)
00676 {
00677 Sys_MarkMapModified();
00678 }
00679
00680 if (bLocalConvert)
00681 g_qeglobals.bNeedConvert = false;
00682 }
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692 void Brush_SplitBrushByFace (brush_t *in, face_t *f, brush_t **front, brush_t **back)
00693 {
00694 brush_t *b;
00695 face_t *nf;
00696 vec3_t temp;
00697
00698 b = Brush_Clone (in);
00699 nf = Face_Clone (f);
00700
00701 nf->texdef = b->brush_faces->texdef;
00702 nf->next = b->brush_faces;
00703 b->brush_faces = nf;
00704
00705 Brush_Build( b );
00706 Brush_RemoveEmptyFaces ( b );
00707 if ( !b->brush_faces )
00708 {
00709 Brush_Free (b);
00710 *back = NULL;
00711 }
00712 else
00713 {
00714 Entity_LinkBrush (in->owner, b);
00715 *back = b;
00716 }
00717
00718 b = Brush_Clone (in);
00719 nf = Face_Clone (f);
00720
00721 VectorCopy (nf->planepts[0], temp);
00722 VectorCopy (nf->planepts[1], nf->planepts[0]);
00723 VectorCopy (temp, nf->planepts[1]);
00724
00725 nf->texdef = b->brush_faces->texdef;
00726 nf->next = b->brush_faces;
00727 b->brush_faces = nf;
00728
00729 Brush_Build( b );
00730 Brush_RemoveEmptyFaces ( b );
00731 if ( !b->brush_faces )
00732 {
00733 Brush_Free (b);
00734 *front = NULL;
00735 }
00736 else
00737 {
00738 Entity_LinkBrush (in->owner, b);
00739 *front = b;
00740 }
00741 }
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 face_t *Brush_BestSplitFace(brush_t *b)
00752 {
00753 face_t *face, *f, *bestface;
00754 winding_t *front, *back;
00755 int splits, tinywindings, value, bestvalue;
00756
00757 bestvalue = 999999;
00758 bestface = NULL;
00759 for (face = b->brush_faces; face; face = face->next)
00760 {
00761 splits = 0;
00762 tinywindings = 0;
00763 for (f = b->brush_faces; f; f = f->next)
00764 {
00765 if (f == face) continue;
00766
00767 Winding_SplitEpsilon(f->face_winding, face->plane.normal, face->plane.dist, 0.1, &front, &back);
00768
00769 if (!front)
00770 {
00771 Winding_Free(back);
00772 }
00773 else if (!back)
00774 {
00775 Winding_Free(front);
00776 }
00777 else
00778 {
00779 splits++;
00780 if (Winding_IsTiny(front)) tinywindings++;
00781 if (Winding_IsTiny(back)) tinywindings++;
00782 }
00783 }
00784 if (splits)
00785 {
00786 value = splits + 50 * tinywindings;
00787 if (value < bestvalue)
00788 {
00789 bestvalue = value;
00790 bestface = face;
00791 }
00792 }
00793 }
00794 return bestface;
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809 brush_t *Brush_MakeConvexBrushes(brush_t *b)
00810 {
00811 brush_t *front, *back, *end;
00812 face_t *face;
00813
00814 b->next = NULL;
00815 face = Brush_BestSplitFace(b);
00816 if (!face) return b;
00817 Brush_SplitBrushByFace(b, face, &front, &back);
00818
00819 if (!front && !back) return b;
00820 Brush_Free(b);
00821 if (!front)
00822 return Brush_MakeConvexBrushes(back);
00823 b = Brush_MakeConvexBrushes(front);
00824 if (back)
00825 {
00826 for (end = b; end->next; end = end->next);
00827 end->next = Brush_MakeConvexBrushes(back);
00828 }
00829 return b;
00830 }
00831
00832
00833
00834
00835
00836
00837 int Brush_Convex(brush_t *b)
00838 {
00839 face_t *face1, *face2;
00840
00841 for (face1 = b->brush_faces; face1; face1 = face1->next)
00842 {
00843 if (!face1->face_winding) continue;
00844 for (face2 = b->brush_faces; face2; face2 = face2->next)
00845 {
00846 if (face1 == face2) continue;
00847 if (!face2->face_winding) continue;
00848 if (Winding_PlanesConcave(face1->face_winding, face2->face_winding,
00849 face1->plane.normal, face2->plane.normal,
00850 face1->plane.dist, face2->plane.dist))
00851 {
00852 return false;
00853 }
00854 }
00855 }
00856 return true;
00857 }
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876 #define MAX_MOVE_FACES 64
00877 #define INTERSECT_EPSILON 0.1
00878 #define POINT_EPSILON 0.3
00879
00880 int Brush_MoveVertex_old1(brush_t *b, vec3_t vertex, vec3_t delta, vec3_t end, bool bSnap)
00881 {
00882 face_t *f, *face, *newface, *lastface, *nextface;
00883 face_t *movefaces[MAX_MOVE_FACES];
00884 int movefacepoints[MAX_MOVE_FACES];
00885 winding_t *w, tmpw;
00886 int i, j, k, nummovefaces, result;
00887 float dot;
00888
00889 result = false;
00890
00891 tmpw.numpoints = 3;
00892 tmpw.maxpoints = 3;
00893 VectorAdd(vertex, delta, end);
00894
00895 if (bSnap)
00896 for (i = 0; i < 3; i++)
00897 end[i] = floor(end[i] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
00898
00899
00900 nummovefaces = 0;
00901 for (face = b->brush_faces; face; face = face->next)
00902 {
00903 w = face->face_winding;
00904 if (!w) continue;
00905 for (i = 0; i < w->numpoints; i++)
00906 {
00907 if (Point_Equal(w->points[i], vertex, POINT_EPSILON))
00908 {
00909 if (face->face_winding->numpoints <= 3)
00910 {
00911 movefacepoints[nummovefaces] = i;
00912 movefaces[nummovefaces++] = face;
00913 break;
00914 }
00915 dot = DotProduct(end, face->plane.normal) - face->plane.dist;
00916
00917 if (dot > 0.1)
00918 {
00919
00920 for (k = i; k < i + w->numpoints-3; k++)
00921 {
00922 VectorCopy(w->points[i], tmpw.points[0]);
00923 VectorCopy(w->points[(k+1) % w->numpoints], tmpw.points[1]);
00924 VectorCopy(w->points[(k+2) % w->numpoints], tmpw.points[2]);
00925
00926 newface = Face_Clone(face);
00927
00928 for (f = face; f->original; f = f->original) ;
00929 newface->original = f;
00930
00931 if (newface->face_winding) Winding_Free(newface->face_winding);
00932 newface->face_winding = Winding_Clone(&tmpw);
00933
00934 newface->d_texture = Texture_ForName( newface->texdef.name );
00935
00936 newface->next = b->brush_faces;
00937 b->brush_faces = newface;
00938
00939 movefacepoints[nummovefaces] = 0;
00940 movefaces[nummovefaces++] = newface;
00941 }
00942
00943 VectorCopy(w->points[(i-2+w->numpoints) % w->numpoints], tmpw.points[0]);
00944 VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[1]);
00945 VectorCopy(w->points[i], tmpw.points[2]);
00946 Winding_Free(face->face_winding);
00947 face->face_winding = Winding_Clone(&tmpw);
00948
00949 movefacepoints[nummovefaces] = 2;
00950 movefaces[nummovefaces++] = face;
00951 }
00952 else
00953 {
00954
00955 VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[0]);
00956 VectorCopy(w->points[i], tmpw.points[1]);
00957 VectorCopy(w->points[(i+1) % w->numpoints], tmpw.points[2]);
00958
00959 Winding_RemovePoint(w, i);
00960
00961 Face_SetColor(b, face, 1.0);
00962 for (j = 0; j < w->numpoints; j++)
00963 EmitTextureCoordinates(w->points[j], face->d_texture, face);
00964
00965 newface = Face_Clone(face);
00966
00967 for (f = face; f->original; f = f->original) ;
00968 newface->original = f;
00969
00970 if (newface->face_winding) Winding_Free(newface->face_winding);
00971 newface->face_winding = Winding_Clone(&tmpw);
00972
00973 newface->d_texture = Texture_ForName( newface->texdef.name );
00974
00975 newface->next = b->brush_faces;
00976 b->brush_faces = newface;
00977
00978 movefacepoints[nummovefaces] = 1;
00979 movefaces[nummovefaces++] = newface;
00980 }
00981 break;
00982 }
00983 }
00984 }
00985
00986
00987
00988
00989 int l;
00990 vec3_t p1, p2;
00991 winding_t *w2;
00992 plane_t plane;
00993
00994 face = NULL;
00995 VectorCopy(vertex, tmpw.points[1]);
00996 VectorCopy(end, tmpw.points[2]);
00997 for (face = b->brush_faces; face; face = face->next)
00998 {
00999 for (i = 0; i < nummovefaces; i++)
01000 {
01001 if (face == movefaces[i])
01002 break;
01003 }
01004 if (i < nummovefaces)
01005 continue;
01006
01007 if (Winding_VectorIntersect(face->face_winding, &face->plane, vertex, end, INTERSECT_EPSILON))
01008 break;
01009
01010 if (abs(DotProduct(face->plane.normal, end) - face->plane.dist) < 0.5)
01011 {
01012
01013 if (Winding_PointInside(face->face_winding, &face->plane, end, 0.5))
01014 break;
01015 }
01016 for (i = 0; i < nummovefaces; i++)
01017 {
01018 w = movefaces[i]->face_winding;
01019 j = movefacepoints[i];
01020 for (k = -1; k <= 1; k += 2)
01021 {
01022
01023 VectorCopy(w->points[(j + k + w->numpoints) % w->numpoints], tmpw.points[0]);
01024 if (Winding_VectorIntersect(face->face_winding, &face->plane, tmpw.points[0], end, INTERSECT_EPSILON))
01025 {
01026
01027
01028
01029 }
01030
01031 Winding_Plane(&tmpw, plane.normal, &plane.dist);
01032 w2 = face->face_winding;
01033 for (l = 0; l < w2->numpoints; l++)
01034 {
01035 VectorCopy(w2->points[l], p1);
01036 if (Point_Equal(p1, tmpw.points[0], POINT_EPSILON)) continue;
01037 VectorCopy(w2->points[(l+1) % w2->numpoints], p2);
01038 if (Point_Equal(p2, tmpw.points[0], POINT_EPSILON)) continue;
01039 if (Winding_VectorIntersect(&tmpw, &plane, p1, p2, INTERSECT_EPSILON))
01040 break;
01041 }
01042 if (l < w2->numpoints)
01043 {
01044
01045
01046 break;
01047 }
01048 }
01049 if (k <= 1) break;
01050 }
01051 if (i < nummovefaces)
01052 break;
01053 }
01054 if (!face)
01055 {
01056
01057
01058 for (i = 0; i < nummovefaces; i++)
01059 {
01060 VectorCopy(end, movefaces[i]->face_winding->points[movefacepoints[i]]);
01061
01062 for (j = 0; j < 3; j++)
01063 {
01064 VectorCopy(movefaces[i]->face_winding->points[j], movefaces[i]->planepts[j]);
01065 }
01066 Face_MakePlane(movefaces[i]);
01067 }
01068 result = true;
01069 }
01070
01071 for (i = 0; i < nummovefaces; i++)
01072 {
01073 Face_SetColor(b, movefaces[i], 1.0);
01074 for (j = 0; j < movefaces[i]->face_winding->numpoints; j++)
01075 EmitTextureCoordinates(movefaces[i]->face_winding->points[j], movefaces[i]->d_texture, movefaces[i]);
01076 }
01077
01078
01079 lastface = NULL;
01080 for (face = b->brush_faces; face; face = nextface)
01081 {
01082 nextface = face->next;
01083 if (!face->original)
01084 {
01085 lastface = face;
01086 continue;
01087 }
01088 if (!Plane_Equal(&face->plane, &face->original->plane, false))
01089 {
01090 lastface = face;
01091 continue;
01092 }
01093 w = Winding_TryMerge(face->face_winding, face->original->face_winding, face->plane.normal, true);
01094 if (!w)
01095 {
01096 lastface = face;
01097 continue;
01098 }
01099 Winding_Free(face->original->face_winding);
01100 face->original->face_winding = w;
01101
01102 Face_SetColor(b, face->original, 1.0);
01103 for (j = 0; j < face->original->face_winding->numpoints; j++)
01104 EmitTextureCoordinates(face->original->face_winding->points[j], face->original->d_texture, face->original);
01105
01106 if (lastface) lastface->next = face->next;
01107 else b->brush_faces = face->next;
01108 Face_Free(face);
01109 }
01110 return result;
01111 }
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124 #define MAX_MOVE_FACES 64
01125 #define INTERSECT_EPSILON 0.1
01126 #define POINT_EPSILON 0.3
01127
01128 int Brush_MoveVertex_old2(brush_t *b, vec3_t vertex, vec3_t delta, vec3_t end, bool bSnap)
01129 {
01130 face_t *f, *face, *newface, *lastface, *nextface;
01131 face_t *movefaces[MAX_MOVE_FACES];
01132 int movefacepoints[MAX_MOVE_FACES];
01133 winding_t *w, tmpw;
01134 int i, j, k, nummovefaces, result;
01135 float dot;
01136
01137 result = true;
01138
01139 tmpw.numpoints = 3;
01140 tmpw.maxpoints = 3;
01141 VectorAdd(vertex, delta, end);
01142
01143 if (bSnap)
01144 for (i = 0; i < 3; i++)
01145 end[i] = floor(end[i] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
01146
01147
01148 nummovefaces = 0;
01149 for (face = b->brush_faces; face; face = face->next)
01150 {
01151 w = face->face_winding;
01152 if (!w) continue;
01153 for (i = 0; i < w->numpoints; i++)
01154 {
01155 if (Point_Equal(w->points[i], vertex, POINT_EPSILON))
01156 {
01157 if (face->face_winding->numpoints <= 3)
01158 {
01159 movefacepoints[nummovefaces] = i;
01160 movefaces[nummovefaces++] = face;
01161 break;
01162 }
01163 dot = DotProduct(end, face->plane.normal) - face->plane.dist;
01164
01165 if (dot > 0.1)
01166 {
01167
01168 for (k = i; k < i + w->numpoints-3; k++)
01169 {
01170 VectorCopy(w->points[i], tmpw.points[0]);
01171 VectorCopy(w->points[(k+1) % w->numpoints], tmpw.points[1]);
01172 VectorCopy(w->points[(k+2) % w->numpoints], tmpw.points[2]);
01173
01174 newface = Face_Clone(face);
01175
01176 for (f = face; f->original; f = f->original) ;
01177 newface->original = f;
01178
01179 if (newface->face_winding) Winding_Free(newface->face_winding);
01180 newface->face_winding = Winding_Clone(&tmpw);
01181
01182 newface->d_texture = Texture_ForName( newface->texdef.name );
01183
01184 newface->next = b->brush_faces;
01185 b->brush_faces = newface;
01186
01187 movefacepoints[nummovefaces] = 0;
01188 movefaces[nummovefaces++] = newface;
01189 }
01190
01191 VectorCopy(w->points[(i-2+w->numpoints) % w->numpoints], tmpw.points[0]);
01192 VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[1]);
01193 VectorCopy(w->points[i], tmpw.points[2]);
01194 Winding_Free(face->face_winding);
01195 face->face_winding = Winding_Clone(&tmpw);
01196
01197 movefacepoints[nummovefaces] = 2;
01198 movefaces[nummovefaces++] = face;
01199 }
01200 else
01201 {
01202
01203 VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[0]);
01204 VectorCopy(w->points[i], tmpw.points[1]);
01205 VectorCopy(w->points[(i+1) % w->numpoints], tmpw.points[2]);
01206
01207 Winding_RemovePoint(w, i);
01208
01209 Face_SetColor(b, face, 1.0);
01210 for (j = 0; j < w->numpoints; j++)
01211 EmitTextureCoordinates(w->points[j], face->d_texture, face);
01212
01213 newface = Face_Clone(face);
01214
01215 for (f = face; f->original; f = f->original) ;
01216 newface->original = f;
01217
01218 if (newface->face_winding) Winding_Free(newface->face_winding);
01219 newface->face_winding = Winding_Clone(&tmpw);
01220
01221 newface->d_texture = Texture_ForName( newface->texdef.name );
01222
01223 newface->next = b->brush_faces;
01224 b->brush_faces = newface;
01225
01226 movefacepoints[nummovefaces] = 1;
01227 movefaces[nummovefaces++] = newface;
01228 }
01229 break;
01230 }
01231 }
01232 }
01233
01234
01235
01236
01237 for (i = 0; i < nummovefaces; i++)
01238 {
01239
01240 VectorCopy(end, movefaces[i]->face_winding->points[movefacepoints[i]]);
01241
01242 for (j = 0; j < 3; j++)
01243 {
01244 VectorCopy(movefaces[i]->face_winding->points[j], movefaces[i]->planepts[j]);
01245 }
01246 Face_MakePlane(movefaces[i]);
01247 }
01248
01249 if (!Brush_Convex(b))
01250 {
01251 for (i = 0; i < nummovefaces; i++)
01252 {
01253
01254 VectorCopy(vertex, movefaces[i]->face_winding->points[movefacepoints[i]]);
01255
01256 for (j = 0; j < 3; j++)
01257 {
01258 VectorCopy(movefaces[i]->face_winding->points[j], movefaces[i]->planepts[j]);
01259 }
01260 Face_MakePlane(movefaces[i]);
01261 }
01262 result = false;
01263 }
01264
01265 for (i = 0; i < nummovefaces; i++)
01266 {
01267 Face_SetColor(b, movefaces[i], 1.0);
01268 for (j = 0; j < movefaces[i]->face_winding->numpoints; j++)
01269 EmitTextureCoordinates(movefaces[i]->face_winding->points[j], movefaces[i]->d_texture, movefaces[i]);
01270 }
01271
01272
01273 lastface = NULL;
01274 for (face = b->brush_faces; face; face = nextface)
01275 {
01276 nextface = face->next;
01277 if (!face->original)
01278 {
01279 lastface = face;
01280 continue;
01281 }
01282 if (!Plane_Equal(&face->plane, &face->original->plane, false))
01283 {
01284 lastface = face;
01285 continue;
01286 }
01287 w = Winding_TryMerge(face->face_winding, face->original->face_winding, face->plane.normal, true);
01288 if (!w)
01289 {
01290 lastface = face;
01291 continue;
01292 }
01293 Winding_Free(face->original->face_winding);
01294 face->original->face_winding = w;
01295
01296 Face_SetColor(b, face->original, 1.0);
01297 for (j = 0; j < face->original->face_winding->numpoints; j++)
01298 EmitTextureCoordinates(face->original->face_winding->points[j], face->original->d_texture, face->original);
01299
01300 if (lastface) lastface->next = face->next;
01301 else b->brush_faces = face->next;
01302 Face_Free(face);
01303 }
01304 return result;
01305 }
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318 #define MAX_MOVE_FACES 64
01319
01320 int Brush_MoveVertex(brush_t *b, vec3_t vertex, vec3_t delta, vec3_t end, bool bSnap)
01321 {
01322 face_t *f, *face, *newface, *lastface, *nextface;
01323 face_t *movefaces[MAX_MOVE_FACES];
01324 int movefacepoints[MAX_MOVE_FACES];
01325 winding_t *w, tmpw;
01326 vec3_t start, mid;
01327 plane_t plane;
01328 int i, j, k, nummovefaces, result, done;
01329 float dot, front, back, frac, smallestfrac;
01330
01331 result = true;
01332
01333 tmpw.numpoints = 3;
01334 tmpw.maxpoints = 3;
01335 VectorCopy(vertex, start);
01336 VectorAdd(vertex, delta, end);
01337
01338 if (bSnap)
01339 for (i = 0; i < 3; i++)
01340 end[i] = floor(end[i] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
01341
01342 VectorCopy(end, mid);
01343
01344 if (Point_Equal(start, end, 0.3)) return false;
01345
01346 for (face = b->brush_faces; face; face = face->next)
01347 {
01348 w = face->face_winding;
01349 if (!w) continue;
01350 for (i = 0; i < w->numpoints; i++)
01351 {
01352 if (Point_Equal(w->points[i], end, 0.3))
01353 {
01354 VectorCopy(vertex, end);
01355 return false;
01356 }
01357 }
01358 }
01359
01360 done = false;
01361 while(!done)
01362 {
01363
01364
01365 nummovefaces = 0;
01366 for (face = b->brush_faces; face; face = face->next)
01367 {
01368 w = face->face_winding;
01369 if (!w) continue;
01370 for (i = 0; i < w->numpoints; i++)
01371 {
01372 if (Point_Equal(w->points[i], start, 0.2))
01373 {
01374 if (face->face_winding->numpoints <= 3)
01375 {
01376 movefacepoints[nummovefaces] = i;
01377 movefaces[nummovefaces++] = face;
01378 break;
01379 }
01380 dot = DotProduct(end, face->plane.normal) - face->plane.dist;
01381
01382 if (dot > 0.1)
01383 {
01384
01385 for (k = i; k < i + w->numpoints-3; k++)
01386 {
01387 VectorCopy(w->points[i], tmpw.points[0]);
01388 VectorCopy(w->points[(k+1) % w->numpoints], tmpw.points[1]);
01389 VectorCopy(w->points[(k+2) % w->numpoints], tmpw.points[2]);
01390
01391 newface = Face_Clone(face);
01392
01393 for (f = face; f->original; f = f->original) ;
01394 newface->original = f;
01395
01396 if (newface->face_winding) Winding_Free(newface->face_winding);
01397 newface->face_winding = Winding_Clone(&tmpw);
01398
01399 newface->d_texture = Texture_ForName( newface->texdef.name );
01400
01401 newface->next = b->brush_faces;
01402 b->brush_faces = newface;
01403
01404 movefacepoints[nummovefaces] = 0;
01405 movefaces[nummovefaces++] = newface;
01406 }
01407
01408 VectorCopy(w->points[(i-2+w->numpoints) % w->numpoints], tmpw.points[0]);
01409 VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[1]);
01410 VectorCopy(w->points[i], tmpw.points[2]);
01411 Winding_Free(face->face_winding);
01412 face->face_winding = Winding_Clone(&tmpw);
01413
01414 movefacepoints[nummovefaces] = 2;
01415 movefaces[nummovefaces++] = face;
01416 }
01417 else
01418 {
01419
01420 VectorCopy(w->points[(i-1+w->numpoints) % w->numpoints], tmpw.points[0]);
01421 VectorCopy(