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
00026
00027
00028 CPtrArray g_SelectedFaces;
00029 CPtrArray g_SelectedFaceBrushes;
00030 CPtrArray& g_ptrSelectedFaces = g_SelectedFaces;
00031 CPtrArray& g_ptrSelectedFaceBrushes = g_SelectedFaceBrushes;
00032
00033
00034 void clearSelection() {
00035 g_qeglobals.d_select_mode = sel_brush;
00036 g_qeglobals.selectObject = NULL;
00037 }
00038
00039
00040
00041
00042
00043
00044 #define DIST_START 999999
00045 trace_t Test_Ray (vec3_t origin, vec3_t dir, int flags)
00046 {
00047 brush_t *brush;
00048 face_t *face;
00049 float dist;
00050 trace_t t;
00051
00052 memset (&t, 0, sizeof(t));
00053 t.dist = DIST_START;
00054
00055 if (flags & SF_CYCLE)
00056 {
00057 CPtrArray array;
00058 brush_t *pToSelect = (selected_brushes.next != &selected_brushes) ? selected_brushes.next : NULL;
00059 Select_Deselect();
00060
00061
00062 for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
00063 {
00064
00065
00066
00067 if (FilterBrush (brush))
00068 continue;
00069
00070 if (!g_PrefsDlg.m_bSelectCurves && brush->patchBrush)
00071 continue;
00072
00073 if( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush )
00074 continue;
00075
00076
00077
00078
00079 face = Brush_Ray (origin, dir, brush, &dist);
00080
00081 if (face)
00082 {
00083 if ( brush->terrainBrush )
00084 {
00085 Terrain_Ray( origin, dir, brush, &dist );
00086 if( dist == 0 )
00087 {
00088
00089 continue;
00090 }
00091 }
00092 array.Add(brush);
00093 }
00094 }
00095
00096 int nSize = array.GetSize();
00097 if (nSize > 0)
00098 {
00099 bool bFound = false;
00100 for (int i = 0; i < nSize; i++)
00101 {
00102 brush_t *b = reinterpret_cast<brush_t*>(array.GetAt(i));
00103
00104 if (b == pToSelect)
00105 {
00106
00107 int n = (i > 0) ? i-1 : nSize-1;
00108 pToSelect = reinterpret_cast<brush_t*>(array.GetAt(n));
00109 bFound = true;
00110 break;
00111 }
00112 }
00113 if (!bFound)
00114 pToSelect = reinterpret_cast<brush_t*>(array.GetAt(0));
00115 }
00116 if (pToSelect)
00117 {
00118 face = Brush_Ray (origin, dir, pToSelect, &dist);
00119 if ( pToSelect->terrainBrush )
00120 {
00121 t.terraface = Terrain_Ray( origin, dir, pToSelect, &dist );
00122 }
00123
00124 t.dist = dist;
00125 t.brush = pToSelect;
00126 t.face = face;
00127 t.selected = false;
00128 return t;
00129 }
00130 }
00131
00132 if (! (flags & SF_SELECTED_ONLY) )
00133 {
00134 for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
00135 {
00136 if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity)
00137 continue;
00138
00139 if (FilterBrush (brush))
00140 continue;
00141
00142 if (!g_PrefsDlg.m_bSelectCurves && brush->patchBrush)
00143 continue;
00144
00145 if( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush )
00146 continue;
00147
00148
00149
00150
00151 face = Brush_Ray (origin, dir, brush, &dist);
00152 if ( face ) {
00153 if ( brush->terrainBrush )
00154 {
00155 t.terraface = Terrain_Ray( origin, dir, brush, &dist );
00156 }
00157 }
00158 if (dist > 0 && dist < t.dist)
00159 {
00160 t.dist = dist;
00161 t.brush = brush;
00162 t.face = face;
00163 t.selected = false;
00164 }
00165 }
00166 }
00167
00168
00169 for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next)
00170 {
00171 if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity)
00172 continue;
00173
00174 if (FilterBrush (brush))
00175 continue;
00176
00177 if (!g_PrefsDlg.m_bSelectCurves && brush->patchBrush)
00178 continue;
00179
00180 if( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush )
00181 continue;
00182
00183 face = Brush_Ray (origin, dir, brush, &dist);
00184 if ( face ) {
00185 if ( brush->terrainBrush )
00186 {
00187 t.terraface = Terrain_Ray( origin, dir, brush, &dist );
00188 }
00189 }
00190 if (dist > 0 && dist < t.dist)
00191 {
00192 t.dist = dist;
00193 t.brush = brush;
00194 t.face = face;
00195 t.selected = true;
00196 }
00197 }
00198
00199
00200
00201 if ( (flags & SF_ENTITIES_FIRST) && t.brush == NULL)
00202 return Test_Ray (origin, dir, flags - SF_ENTITIES_FIRST);
00203
00204 return t;
00205
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215 void Select_Brush (brush_t *brush, bool bComplete, bool bStatus)
00216 {
00217 brush_t *b;
00218 entity_t *e;
00219
00220 g_ptrSelectedFaces.RemoveAll();
00221 g_ptrSelectedFaceBrushes.RemoveAll();
00222
00223 if (g_qeglobals.d_select_count < 2)
00224 g_qeglobals.d_select_order[g_qeglobals.d_select_count] = brush;
00225 g_qeglobals.d_select_count++;
00226
00227
00228
00229
00230 e = brush->owner;
00231 if (e)
00232 {
00233
00234 if (e != world_entity && bComplete == true)
00235 {
00236 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
00237 if (b->owner == e)
00238 goto singleselect;
00239 for (b=e->brushes.onext ; b != &e->brushes ; b=b->onext)
00240 {
00241 Brush_RemoveFromList (b);
00242 Brush_AddToList (b, &selected_brushes);
00243 }
00244 }
00245 else
00246 {
00247 singleselect:
00248 Brush_RemoveFromList (brush);
00249 Brush_AddToList (brush, &selected_brushes);
00250 UpdateSurfaceDialog();
00251 UpdatePatchInspector();
00252 }
00253
00254 if (e->eclass)
00255 {
00256 UpdateEntitySel(brush->owner->eclass);
00257 }
00258 }
00259 if (bStatus)
00260 {
00261 vec3_t vMin, vMax, vSize;
00262 Select_GetBounds (vMin, vMax);
00263 VectorSubtract(vMax, vMin, vSize);
00264 CString strStatus;
00265 strStatus.Format("Selection X:: %.1f Y:: %.1f Z:: %.1f", vSize[0], vSize[1], vSize[2]);
00266 g_pParentWnd->SetStatusText(2, strStatus);
00267 }
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 void Select_Ray (vec3_t origin, vec3_t dir, int flags)
00279 {
00280 trace_t t;
00281
00282 t = Test_Ray (origin, dir, flags);
00283 if (!t.brush)
00284 return;
00285
00286 if (flags == SF_SINGLEFACE)
00287 {
00288 int nCount = g_SelectedFaces.GetSize();
00289 bool bOk = true;
00290 for (int i = 0; i < nCount; i++)
00291 {
00292 if (t.face == reinterpret_cast<face_t*>(g_SelectedFaces.GetAt(i)))
00293 {
00294 bOk = false;
00295
00296 g_SelectedFaces.RemoveAt(i, 1);
00297 g_SelectedFaceBrushes.RemoveAt(i, 1);
00298 }
00299 }
00300 if (bOk)
00301 {
00302 g_SelectedFaces.Add(t.face);
00303 g_SelectedFaceBrushes.Add(t.brush);
00304 }
00305
00306
00307 Sys_UpdateWindows (W_ALL);
00308 clearSelection();
00309
00310 brushprimit_texdef_t brushprimit_texdef;
00311 ConvertTexMatWithQTexture ( &t.face->brushprimit_texdef, t.face->d_texture, &brushprimit_texdef, NULL );
00312 Texture_SetTexture ( &t.face->texdef, &brushprimit_texdef, false, GETPLUGINTEXDEF(t.face), false );
00313 UpdateSurfaceDialog();
00314 return;
00315 }
00316
00317
00318
00319 clearSelection();
00320
00321 if (t.selected)
00322 {
00323 Brush_RemoveFromList (t.brush);
00324 Brush_AddToList (t.brush, &active_brushes);
00325 UpdatePatchInspector();
00326 }
00327 else
00328 {
00329 Select_Brush (t.brush, !(GetKeyState(VK_MENU) & 0x8000));
00330 }
00331
00332 Sys_UpdateWindows (W_ALL);
00333 }
00334
00335
00336 void Select_Delete (void)
00337 {
00338 brush_t *brush;
00339
00340 g_ptrSelectedFaces.RemoveAll();
00341 g_ptrSelectedFaceBrushes.RemoveAll();
00342
00343
00344 clearSelection();
00345
00346 g_qeglobals.d_select_count = 0;
00347 g_qeglobals.d_num_move_points = 0;
00348 while (selected_brushes.next != &selected_brushes)
00349 {
00350 brush = selected_brushes.next;
00351 if (brush->patchBrush)
00352 {
00353
00354 Patch_Delete(brush->pPatch);
00355 }
00356 if (brush->terrainBrush)
00357 {
00358 Terrain_Delete(brush->pTerrain );
00359 }
00360
00361 Brush_Free (brush);
00362 }
00363
00364
00365
00366 Sys_UpdateWindows (W_ALL);
00367 }
00368
00369 void Select_Deselect (bool bDeselectFaces)
00370 {
00371 brush_t *b;
00372
00373 Patch_Deselect();
00374
00375 g_pParentWnd->ActiveXY()->UndoClear();
00376
00377 g_qeglobals.d_workcount++;
00378 g_qeglobals.d_select_count = 0;
00379 g_qeglobals.d_num_move_points = 0;
00380 b = selected_brushes.next;
00381
00382 if (b == &selected_brushes)
00383 {
00384 if (bDeselectFaces)
00385 {
00386 g_ptrSelectedFaces.RemoveAll();
00387 g_ptrSelectedFaceBrushes.RemoveAll();
00388
00389 }
00390 Sys_UpdateWindows (W_ALL);
00391 return;
00392 }
00393
00394 if (bDeselectFaces)
00395 {
00396 g_ptrSelectedFaces.RemoveAll();
00397 g_ptrSelectedFaceBrushes.RemoveAll();
00398
00399 }
00400
00401 clearSelection();
00402
00403
00404 if (b->mins[2] < b->maxs[2])
00405 {
00406 g_qeglobals.d_new_brush_bottom_z = b->mins[2];
00407 g_qeglobals.d_new_brush_top_z = b->maxs[2];
00408 }
00409
00410 selected_brushes.next->prev = &active_brushes;
00411 selected_brushes.prev->next = active_brushes.next;
00412 active_brushes.next->prev = selected_brushes.prev;
00413 active_brushes.next = selected_brushes.next;
00414 selected_brushes.prev = selected_brushes.next = &selected_brushes;
00415
00416 Sys_UpdateWindows (W_ALL);
00417 }
00418
00419
00420
00421
00422
00423
00424 void Select_Move (vec3_t delta, bool bSnap)
00425 {
00426 brush_t *b;
00427
00428
00429
00430 for (b = selected_brushes.next ; b != &selected_brushes ; b=b->next)
00431 Brush_Move (b, delta, bSnap);
00432
00433 vec3_t vMin, vMax;
00434 Select_GetBounds (vMin, vMax);
00435 CString strStatus;
00436 strStatus.Format("Origin X:: %.1f Y:: %.1f Z:: %.1f", vMin[0], vMax[1], vMax[2]);
00437 g_pParentWnd->SetStatusText(2, strStatus);
00438
00439
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 void Select_Clone (void)
00451 {
00452 #if 1
00453 ASSERT(g_pParentWnd->ActiveXY());
00454 g_bScreenUpdates = false;
00455 g_pParentWnd->ActiveXY()->Copy();
00456 g_pParentWnd->ActiveXY()->Paste();
00457 g_pParentWnd->NudgeSelection(2, g_qeglobals.d_gridsize);
00458 g_pParentWnd->NudgeSelection(3, g_qeglobals.d_gridsize);
00459 g_bScreenUpdates = true;
00460 Sys_UpdateWindows(W_ALL);
00461 #else
00462
00463 brush_t *b, *b2, *n, *next, *next2;
00464 vec3_t delta;
00465 entity_t *e;
00466
00467 g_qeglobals.d_workcount++;
00468 clearSelection();
00469
00470 delta[0] = g_qeglobals.d_gridsize;
00471 delta[1] = g_qeglobals.d_gridsize;
00472 delta[2] = 0;
00473
00474 for (b=selected_brushes.next ; b != &selected_brushes ; b=next)
00475 {
00476 next = b->next;
00477
00478 if (b->owner == world_entity)
00479 {
00480 n = Brush_Clone (b);
00481 Brush_AddToList (n, &active_brushes);
00482 Entity_LinkBrush (world_entity, n);
00483 Brush_Build( n );
00484 Brush_Move (b, delta);
00485 continue;
00486 }
00487
00488 e = Entity_Clone (b->owner);
00489
00490 DeleteKey (e, "target");
00491 DeleteKey (e, "targetname");
00492
00493
00494 if (b->owner->eclass->fixedsize)
00495 {
00496 n = Brush_Clone (b);
00497 Brush_AddToList (n, &active_brushes);
00498 Entity_LinkBrush (e, n);
00499 Brush_Build( n );
00500 Brush_Move (b, delta);
00501 continue;
00502 }
00503
00504
00505
00506 next = &selected_brushes;
00507
00508 for ( b2 = b ; b2 != &selected_brushes ; b2=next2)
00509 {
00510 next2 = b2->next;
00511 if (b2->owner != b->owner)
00512 {
00513 if (next == &selected_brushes)
00514 next = b2;
00515 continue;
00516 }
00517
00518
00519
00520 Brush_RemoveFromList (b2);
00521 Brush_AddToList (b2, &selected_brushes);
00522
00523 n = Brush_Clone (b2);
00524 Brush_AddToList (n, &active_brushes);
00525 Entity_LinkBrush (e, n);
00526 Brush_Build( n );
00527 Brush_Move (b2, delta, true);
00528 }
00529
00530 }
00531 Sys_UpdateWindows (W_ALL);
00532 #endif
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 void WINAPI Select_SetTexture (texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale, void* pPlugTexdef )
00550 {
00551 brush_t *b;
00552 int nCount = g_ptrSelectedFaces.GetSize();
00553 if (nCount > 0)
00554 {
00555 Undo_Start("set face textures");
00556 ASSERT(g_ptrSelectedFaces.GetSize() == g_ptrSelectedFaceBrushes.GetSize());
00557 for (int i = 0; i < nCount; i++)
00558 {
00559 face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i));
00560 brush_t *selBrush = reinterpret_cast<brush_t*>(g_ptrSelectedFaceBrushes.GetAt(i));
00561 Undo_AddBrush(selBrush);
00562 SetFaceTexdef (selBrush, selFace, texdef, brushprimit_texdef, bFitScale, static_cast<IPluginTexdef *>(pPlugTexdef) );
00563 Brush_Build(selBrush, bFitScale);
00564 Undo_EndBrush(selBrush);
00565 }
00566 Undo_End();
00567 }
00568 else if (selected_brushes.next != &selected_brushes)
00569 {
00570 Undo_Start("set brush textures");
00571 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
00572 if (!b->owner->eclass->fixedsize)
00573 {
00574 Undo_AddBrush(b);
00575 Brush_SetTexture (b, texdef, brushprimit_texdef, bFitScale, static_cast<IPluginTexdef *>(pPlugTexdef) );
00576 Undo_EndBrush(b);
00577 }
00578 Undo_End();
00579 }
00580 Sys_UpdateWindows (W_ALL);
00581 }
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 void Select_GetBounds (vec3_t mins, vec3_t maxs)
00593 {
00594 brush_t *b;
00595 int i;
00596
00597 for (i=0 ; i<3 ; i++)
00598 {
00599 mins[i] = 99999;
00600 maxs[i] = -99999;
00601 }
00602
00603 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
00604 for (i=0 ; i<3 ; i++)
00605 {
00606 if (b->mins[i] < mins[i])
00607 mins[i] = b->mins[i];
00608 if (b->maxs[i] > maxs[i])
00609 maxs[i] = b->maxs[i];
00610 }
00611 }
00612
00613
00614 void Select_GetTrueMid (vec3_t mid)
00615 {
00616 vec3_t mins, maxs;
00617 Select_GetBounds (mins, maxs);
00618
00619 for (int i=0 ; i<3 ; i++)
00620 mid[i] = (mins[i] + ((maxs[i] - mins[i]) / 2));
00621 }
00622
00623
00624 void Select_GetMid (vec3_t mid)
00625 {
00626 vec3_t mins, maxs;
00627 int i;
00628
00629 if (g_PrefsDlg.m_bNoClamp)
00630 {
00631 Select_GetTrueMid(mid);
00632 return;
00633 }
00634
00635 Select_GetBounds (mins, maxs);
00636
00637 for (i=0 ; i<3 ; i++)
00638 mid[i] = g_qeglobals.d_gridsize*floor ( ( (mins[i] + maxs[i])*0.5 )/g_qeglobals.d_gridsize );
00639
00640 }
00641
00642 vec3_t select_origin;
00643 vec3_t select_matrix[3];
00644 qboolean select_fliporder;
00645
00646 void Select_ApplyMatrix (bool bSnap, bool bRotation, int nAxis, float fDeg)
00647 {
00648 brush_t *b;
00649 face_t *f;
00650 int i, j;
00651 vec3_t temp;
00652
00653 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
00654 {
00655 for (f=b->brush_faces ; f ; f=f->next)
00656 {
00657 for (i=0 ; i<3 ; i++)
00658 {
00659 VectorSubtract (f->planepts[i], select_origin, temp);
00660 for (j=0 ; j<3 ; j++)
00661 f->planepts[i][j] = DotProduct(temp, select_matrix[j]) + select_origin[j];
00662 }
00663 if (select_fliporder)
00664 {
00665 VectorCopy (f->planepts[0], temp);
00666 VectorCopy (f->planepts[2], f->planepts[0]);
00667 VectorCopy (temp, f->planepts[2]);
00668 }
00669 }
00670
00671 if(b->owner->eclass->fixedsize)
00672 {
00673 if (bRotation && b->owner->md3Class)
00674 {
00675 b->owner->vRotation[nAxis] += fDeg;
00676 }
00677 }
00678
00679 Brush_Build(b, bSnap);
00680
00681 if (b->patchBrush)
00682 {
00683
00684 Patch_ApplyMatrix(b->pPatch, select_origin, select_matrix, bSnap);
00685 }
00686
00687 if (b->terrainBrush)
00688 {
00689 Terrain_ApplyMatrix(b->pTerrain, select_origin, select_matrix, bSnap);
00690 }
00691
00692 }
00693 }
00694
00695 void ProjectOnPlane(vec3_t& normal,float dist,vec3_t& ez, vec3_t& p)
00696 {
00697 if (fabs(ez[0]) == 1)
00698 p[0] = (dist - normal[1] * p[1] - normal[2] * p[2]) / normal[0];
00699 else if (fabs(ez[1]) == 1)
00700 p[1] = (dist - normal[0] * p[0] - normal[2] * p[2]) / normal[1];
00701 else
00702 p[2] = (dist - normal[0] * p[0] - normal[1] * p[1]) / normal[2];
00703 }
00704
00705 void Back(vec3_t& dir, vec3_t& p)
00706 {
00707 if (fabs(dir[0]) == 1)
00708 p[0] = 0;
00709 else if (fabs(dir[1]) == 1)
00710 p[1] = 0;
00711 else p[2] = 0;
00712 }
00713
00714
00715
00716
00717 void ComputeScale(vec3_t& rex, vec3_t& rey, vec3_t& p, face_t* f)
00718 {
00719 float px = DotProduct(rex, p);
00720 float py = DotProduct(rey, p);
00721 px *= f->texdef.scale[0];
00722 py *= f->texdef.scale[1];
00723 vec3_t aux;
00724 VectorCopy(rex, aux);
00725 VectorScale(aux, px, aux);
00726 VectorCopy(aux, p);
00727 VectorCopy(rey, aux);
00728 VectorScale(aux, py, aux);
00729 VectorAdd(p, aux, p);
00730 }
00731
00732 void ComputeAbsolute(face_t* f, vec3_t& p1, vec3_t& p2, vec3_t& p3)
00733 {
00734 vec3_t ex,ey,ez;
00735
00736 #ifdef _DEBUG
00737 if (g_qeglobals.m_bBrushPrimitMode)
00738 Sys_Printf("Warning : illegal call of ComputeAbsolute in brush primitive mode\n");
00739 #endif
00740
00741
00742 TextureAxisFromPlane(&f->plane, ex, ey);
00743 CrossProduct(ex, ey, ez);
00744
00745 vec3_t aux;
00746 VectorCopy(ex, aux);
00747 VectorScale(aux, -f->texdef.shift[0], aux);
00748 VectorCopy(aux, p1);
00749 VectorCopy(ey, aux);
00750 VectorScale(aux, -f->texdef.shift[1], aux);
00751 VectorAdd(p1, aux, p1);
00752 VectorCopy(p1, p2);
00753 VectorAdd(p2, ex, p2);
00754 VectorCopy(p1, p3);
00755 VectorAdd(p3, ey, p3);
00756 VectorCopy(ez, aux);
00757 VectorScale(aux, -f->texdef.rotate, aux);
00758 VectorRotate(p1, aux, p1);
00759 VectorRotate(p2, aux, p2);
00760 VectorRotate(p3, aux, p3);
00761
00762 vec3_t rex,rey;
00763 VectorCopy(ex, rex);
00764 VectorRotate(rex, aux, rex);
00765 VectorCopy(ey, rey);
00766 VectorRotate(rey, aux, rey);
00767
00768 ComputeScale(rex,rey,p1,f);
00769 ComputeScale(rex,rey,p2,f);
00770 ComputeScale(rex,rey,p3,f);
00771
00772
00773
00774
00775 ProjectOnPlane(f->plane.normal,f->plane.dist,ez,p1);
00776 ProjectOnPlane(f->plane.normal,f->plane.dist,ez,p2);
00777 ProjectOnPlane(f->plane.normal,f->plane.dist,ez,p3);
00778 };
00779
00780
00781 void AbsoluteToLocal(plane_t normal2, face_t* f, vec3_t& p1, vec3_t& p2, vec3_t& p3)
00782 {
00783 vec3_t ex,ey,ez;
00784
00785 #ifdef _DEBUG
00786 if (g_qeglobals.m_bBrushPrimitMode)
00787 Sys_Printf("Warning : illegal call of AbsoluteToLocal in brush primitive mode\n");
00788 #endif
00789
00790
00791 TextureAxisFromPlane(&normal2, ex, ey);
00792 CrossProduct(ex, ey, ez);
00793
00794
00795 Back(ez,p1);
00796 Back(ez,p2);
00797 Back(ez,p3);
00798
00799 vec3_t aux;
00800
00801 VectorCopy(p2, aux);
00802 VectorSubtract(aux, p1,aux);
00803
00804 float x = DotProduct(aux,ex);
00805 float y = DotProduct(aux,ey);
00806 f->texdef.rotate = 180 * atan2(y,x) / Q_PI;
00807
00808 vec3_t rex,rey;
00809
00810 VectorCopy(ez, aux);
00811 VectorScale(aux, f->texdef.rotate, aux);
00812 VectorCopy(ex, rex);
00813 VectorRotate(rex, aux, rex);
00814 VectorCopy(ey, rey);
00815 VectorRotate(rey, aux, rey);
00816
00817
00818 VectorCopy(p2, aux);
00819 VectorSubtract(aux, p1, aux);
00820 f->texdef.scale[0] = DotProduct(aux, rex);
00821 VectorCopy(p3, aux);
00822 VectorSubtract(aux, p1, aux);
00823 f->texdef.scale[1] = DotProduct(aux, rey);
00824
00825
00826
00827 x = DotProduct(rex,p1);
00828 y = DotProduct(rey,p1);
00829 x /= f->texdef.scale[0];
00830 y /= f->texdef.scale[1];
00831
00832 VectorCopy(rex, p1);
00833 VectorScale(p1, x, p1);
00834 VectorCopy(rey, aux);
00835 VectorScale(aux, y, aux);
00836 VectorAdd(p1, aux, p1);
00837 VectorCopy(ez, aux);
00838 VectorScale(aux, -f->texdef.rotate, aux);
00839 VectorRotate(p1, aux, p1);
00840 f->texdef.shift[0] = -DotProduct(p1, ex);
00841 f->texdef.shift[1] = -DotProduct(p1, ey);
00842
00843
00844
00845 f->texdef.rotate = -f->texdef.rotate;
00846
00847 Clamp(f->texdef.shift[0], f->d_texture->width);
00848 Clamp(f->texdef.shift[1], f->d_texture->height);
00849 Clamp(f->texdef.rotate, 360);
00850
00851 }
00852
00853 void RotateFaceTexture(face_t* f, int nAxis, float fDeg)
00854 {
00855 vec3_t p1,p2,p3, rota;
00856 p1[0] = p1[1] = p1[2] = 0;
00857 VectorCopy(p1, p2);
00858 VectorCopy(p1, p3);
00859 VectorCopy(p1, rota);
00860 ComputeAbsolute(f, p1, p2, p3);
00861
00862 rota[nAxis] = fDeg;
00863 VectorRotate(p1, rota, select_origin, p1);
00864 VectorRotate(p2, rota, select_origin, p2);
00865 VectorRotate(p3, rota, select_origin, p3);
00866
00867 plane_t normal2;
00868 vec3_t vNormal;
00869 vNormal[0] = f->plane.normal[0];
00870 vNormal[1] = f->plane.normal[1];
00871 vNormal[2] = f->plane.normal[2];
00872 VectorRotate(vNormal, rota, vNormal);
00873 normal2.normal[0] = vNormal[0];
00874 normal2.normal[1] = vNormal[1];
00875 normal2.normal[2] = vNormal[2];
00876 AbsoluteToLocal(normal2, f, p1, p2 ,p3);
00877
00878 }
00879
00880 void RotateTextures(int nAxis, float fDeg, vec3_t vOrigin)
00881 {
00882 for (brush_t* b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
00883 {
00884 for (face_t* f=b->brush_faces ; f ; f=f->next)
00885 {
00886 if (g_qeglobals.m_bBrushPrimitMode)
00887 RotateFaceTexture_BrushPrimit( f, nAxis, fDeg, vOrigin );
00888 else
00889 RotateFaceTexture(f, nAxis, fDeg);
00890
00891
00892 }
00893 Brush_Build(b, false);
00894 }
00895 }
00896
00897
00898 void Select_FlipAxis (int axis)
00899 {
00900 int i;
00901
00902 Select_GetMid (select_origin);
00903 for (i=0 ; i<3 ; i++)
00904 {
00905 VectorCopy (vec3_origin, select_matrix[i]);
00906 select_matrix[i][i] = 1;
00907 }
00908 select_matrix[axis][axis] = -1;
00909
00910 select_fliporder = true;
00911 Select_ApplyMatrix (true, false, 0, 0);
00912 Sys_UpdateWindows (W_ALL);
00913 }
00914
00915
00916 void Select_Scale(float x, float y, float z)
00917 {
00918 Select_GetMid (select_origin);
00919 for (brush_t* b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
00920 {
00921 for (face_t* f=b->brush_faces ; f ; f=f->next)
00922 {
00923 for (int i=0 ; i<3 ; i++)
00924 {
00925 f->planepts[i][0] -= select_origin[0];
00926 f->planepts[i][1] -= select_origin[1];
00927 f->planepts[i][2] -= select_origin[2];
00928 f->planepts[i][0] *= x;
00929
00930
00931 f->planepts[i][1] *= y;
00932
00933
00934 f->planepts[i][2] *= z;
00935
00936
00937 f->planepts[i][0] += select_origin[0];
00938 f->planepts[i][1] += select_origin[1];
00939 f->planepts[i][2] += select_origin[2];
00940 }
00941 }
00942 Brush_Build(b, false);
00943 if (b->patchBrush)
00944 {
00945 vec3_t v;
00946 v[0] = x;
00947 v[1] = y;
00948 v[2] = z;
00949
00950 Patch_Scale(b->pPatch, select_origin, v);
00951 }
00952 if (b->terrainBrush)
00953 {
00954 vec3_t v;
00955 v[0] = x;
00956 v[1] = y;
00957 v[2] = z;
00958 Terrain_Scale(b->pTerrain, select_origin, v);
00959 }
00960 }
00961 }
00962
00963 void Select_RotateAxis (int axis, float deg, bool bPaint, bool bMouse)
00964 {
00965 vec3_t temp;
00966 int i, j;
00967 vec_t c, s;
00968
00969 if (deg == 0)
00970 {
00971
00972 return;
00973 }
00974
00975 if (bMouse)
00976 {
00977 VectorCopy(g_pParentWnd->ActiveXY()->RotateOrigin(), select_origin);
00978 }
00979 else
00980 {
00981 Select_GetMid (select_origin);
00982 }
00983
00984 select_fliporder = false;
00985
00986 if (deg == 90)
00987 {
00988 for (i=0 ; i<3 ; i++)
00989 {
00990 VectorCopy (vec3_origin, select_matrix[i]);
00991 select_matrix[i][i] = 1;
00992 }
00993 i = (axis+1)%3;
00994 j = (axis+2)%3;
00995 VectorCopy (select_matrix[i], temp);
00996 VectorCopy (select_matrix[j], select_matrix[i]);
00997 VectorSubtract (vec3_origin, temp, select_matrix[j]);
00998 }
00999 else
01000 {
01001 deg = -deg;
01002 if (deg == -180.0)
01003 {
01004 c = -1;
01005 s = 0;
01006 }
01007 else if (deg == -270.0)
01008 {
01009 c = 0;
01010 s = -1;
01011 }
01012 else
01013 {
01014 c = cos(deg * Q_PI / 180.0);
01015 s = sin(deg * Q_PI / 180.0);
01016 }
01017
01018 for (i=0 ; i<3 ; i++)
01019 {
01020 VectorCopy (vec3_origin, select_matrix[i]);
01021 select_matrix[i][i] = 1;
01022 }
01023
01024 switch (axis)
01025 {
01026 case 0:
01027 select_matrix[1][1] = c;
01028 select_matrix[1][2] = -s;
01029 select_matrix[2][1] = s;
01030 select_matrix[2][2] = c;
01031 break;
01032 case 1:
01033 select_matrix[0][0] = c;
01034 select_matrix[0][2] = s;
01035 select_matrix[2][0] = -s;
01036 select_matrix[2][2] = c;
01037 break;
01038 case 2:
01039 select_matrix[0][0] = c;
01040 select_matrix[0][1] = -s;
01041 select_matrix[1][0] = s;
01042 select_matrix[1][1] = c;
01043 break;
01044 }
01045 }
01046
01047 if (g_PrefsDlg.m_bRotateLock)
01048 RotateTextures(axis, deg, select_origin);
01049 Select_ApplyMatrix(!bMouse, true, axis, deg);
01050
01051 if (bPaint)
01052 Sys_UpdateWindows (W_ALL);
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063 void Select_CompleteTall (void)
01064 {
01065 brush_t *b, *next;
01066
01067 vec3_t mins, maxs;
01068
01069 if (!QE_SingleBrush ())
01070 return;
01071
01072 clearSelection();
01073
01074 VectorCopy (selected_brushes.next->mins, mins);
01075 VectorCopy (selected_brushes.next->maxs, maxs);
01076 Select_Delete ();
01077
01078 int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0;
01079 int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2;
01080
01081 for (b=active_brushes.next ; b != &active_brushes ; b=next)
01082 {
01083 next = b->next;
01084
01085 if ( (b->maxs[nDim1] > maxs[nDim1] || b->mins[nDim1] < mins[nDim1])
01086 || (b->maxs[nDim2] > maxs[nDim2] || b->mins[nDim2] < mins[nDim2]) )
01087 continue;
01088
01089 if (FilterBrush (b))
01090 continue;
01091
01092 Brush_RemoveFromList (b);
01093 Brush_AddToList (b, &selected_brushes);
01094 #if 0
01095
01096 for (i=0 ; i<2 ; i++)
01097 if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i])
01098 break;
01099 if (i == 2)
01100 {
01101 Brush_RemoveFromList (b);
01102 Brush_AddToList (b, &selected_brushes);
01103 }
01104 #endif
01105 }
01106 Sys_UpdateWindows (W_ALL);
01107 }
01108
01109 void Select_PartialTall (void)
01110 {
01111 brush_t *b, *next;
01112
01113 vec3_t mins, maxs;
01114
01115 if (!QE_SingleBrush ())
01116 return;
01117
01118 clearSelection();
01119
01120 VectorCopy (selected_brushes.next->mins, mins);
01121 VectorCopy (selected_brushes.next->maxs, maxs);
01122 Select_Delete ();
01123
01124 int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0;
01125 int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2;
01126
01127 for (b=active_brushes.next ; b != &active_brushes ; b=next)
01128 {
01129 next = b->next;
01130
01131 if ( (b->mins[nDim1] > maxs[nDim1] || b->maxs[nDim1] < mins[nDim1])
01132 || (b->mins[nDim2] > maxs[nDim2] || b->maxs[nDim2] < mins[nDim2]) )
01133 continue;
01134
01135 if (FilterBrush (b))
01136 continue;
01137
01138 Brush_RemoveFromList (b);
01139 Brush_AddToList (b, &selected_brushes);
01140
01141
01142 #if 0
01143
01144 for (i=0 ; i<2 ; i++)
01145 if (b->mins[i] > maxs[i] || b->maxs[i] < mins[i])
01146 break;
01147 if (i == 2)
01148 {
01149 Brush_RemoveFromList (b);
01150 Brush_AddToList (b, &selected_brushes);
01151 }
01152 #endif
01153 }
01154 Sys_UpdateWindows (W_ALL);
01155 }
01156
01157 void Select_Touching (void)
01158 {
01159 brush_t *b, *next;
01160 int i;
01161 vec3_t mins, maxs;
01162
01163 if (!QE_SingleBrush ())
01164 return;
01165
01166 clearSelection();
01167
01168 VectorCopy (selected_brushes.next->mins, mins);
01169 VectorCopy (selected_brushes.next->maxs, maxs);
01170
01171 for (b=active_brushes.next ; b != &active_brushes ; b=next)
01172 {
01173 next = b->next;
01174
01175 if (FilterBrush (b))
01176 continue;
01177
01178 for (i=0 ; i<3 ; i++)
01179 if (b->mins[i] > maxs[i]+1 || b->maxs[i] < mins[i]-1)
01180 break;
01181
01182 if (i == 3)
01183 {
01184 Brush_RemoveFromList (b);
01185 Brush_AddToList (b, &selected_brushes);
01186 }
01187 }
01188 Sys_UpdateWindows (W_ALL);
01189 }
01190
01191 void Select_Inside (void)
01192 {
01193 brush_t *b, *next;
01194 int i;
01195 vec3_t mins, maxs;
01196
01197 if (!QE_SingleBrush ())
01198 return;
01199
01200 clearSelection();
01201
01202 VectorCopy (selected_brushes.next->mins, mins);
01203 VectorCopy (selected_brushes.next->maxs, maxs);
01204 Select_Delete ();
01205
01206 for (b=active_brushes.next ; b != &active_brushes ; b=next)
01207 {
01208 next = b->next;
01209
01210 if (FilterBrush (b))
01211 continue;
01212
01213 for (i=0 ; i<3 ; i++)
01214 if (b->maxs[i] > maxs[i] || b->mins[i] < mins[i])
01215 break;
01216 if (i == 3)
01217 {
01218 Brush_RemoveFromList (b);
01219 Brush_AddToList (b, &selected_brushes);
01220 }
01221 }
01222 Sys_UpdateWindows (W_ALL);
01223 }
01224
01225
01226
01227
01228
01229
01230
01231
01232 void Select_Ungroup(void)
01233 {
01234 int numselectedgroups;
01235 entity_t *e;
01236 brush_t *b, *sb;
01237
01238 numselectedgroups = 0;
01239 for (sb = selected_brushes.next; sb != &selected_brushes; sb = sb->next)
01240 {
01241 e = sb->owner;
01242
01243 if (!e || e == world_entity || e->eclass->fixedsize)
01244 {
01245 continue;
01246 }
01247
01248 for (b = e->brushes.onext; b != &e->brushes; b = e->brushes.onext)
01249 {
01250
01251
01252 Entity_UnlinkBrush (b);
01253 Entity_LinkBrush (world_entity, b);
01254 Brush_Build( b );
01255 b->owner = world_entity;
01256 }
01257 Entity_Free (e);
01258 numselectedgroups++;
01259 }
01260
01261 if (numselectedgroups <= 0)
01262 {
01263 Sys_Printf("No grouped entities selected.\n");
01264 return;
01265 }
01266 Sys_Printf("Ungrouped %d entit%s.\n", numselectedgroups, (numselectedgroups == 1)?"y":"ies");
01267 Sys_UpdateWindows (W_ALL);
01268 }
01269
01270
01271
01272
01273
01274
01275
01276 void Select_MakeStructural (void)
01277 {
01278 brush_t *b;
01279 face_t *f;
01280
01281 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
01282 for (f=b->brush_faces ; f ; f=f->next)
01283 f->texdef.contents &= ~CONTENTS_DETAIL;
01284 Select_Deselect ();
01285 Sys_UpdateWindows (W_ALL);
01286 }
01287
01288 void Select_MakeDetail (void)
01289 {
01290 brush_t *b;
01291 face_t *f;
01292
01293 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
01294 for (f=b->brush_faces ; f ; f=f->next)
01295 f->texdef.contents |= CONTENTS_DETAIL;
01296 Select_Deselect ();
01297 Sys_UpdateWindows (W_ALL);
01298 }
01299
01300 void Select_ShiftTexture(int x, int y)
01301 {
01302 brush_t *b;
01303 face_t *f;
01304
01305 int nFaceCount = g_ptrSelectedFaces.GetSize();
01306
01307 if(selected_brushes.next == &selected_brushes && nFaceCount == 0)
01308 return;
01309
01310 for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
01311 {
01312 for (f=b->brush_faces ; f ; f=f->next)
01313 {
01314 if (g_qeglobals.m_bBrushPrimitMode)
01315 {
01316
01317 Select_ShiftTexture_BrushPrimit( f, x, y );
01318 }
01319 else
01320 {
01321 f->texdef.shift[0] += x;
01322 f->texdef.shift[1] += y;
01323 }
01324 }
01325 Brush_Build(b);
01326 if (b->patchBrush)
01327 {
01328
01329 Patch_ShiftTexture(b->pPatch, x, y);
01330 }
01331 }
01332
01333 if (nFaceCount > 0)
01334 {
01335 for (int i = 0; i < nFaceCount; i++)
01336 {
01337 face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i));
01338 brush_t *selBrush = reinterpret_cast<brush_t*>(g_ptrSelectedFaceBrushes.GetAt(i));
01339 if (g_qeglobals.m_bBrushPrimitMode)
01340 {
01341
01342
01343
01344
01345 g_pParentWnd->GetCamera()->ShiftTexture_BrushPrimit( selFace, x,