more eol-style
[xonotic/netradiant.git] / radiant / surfaceplugin.cpp
1 /*
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 //-----------------------------------------------------------------------------
23 //
24 // DESCRIPTION:
25 // implementation of isurfaceplugin-interface specifics
26
27 #include "stdafx.h"
28
29 void QERApp_GetTwoSelectedPatch( patchMesh_t **p1, patchMesh_t **p2 )
30 {
31   *p1 = NULL; *p2 = NULL;
32   for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next)
33   {
34     if (pb->patchBrush)
35     {
36       if (!(*p1))
37         *p1 = pb->pPatch;
38       else if (!(*p2))
39       {
40         *p2 = pb->pPatch;
41         return;
42       }
43     }
44   }
45 #ifdef _DEBUG
46   Sys_Printf("WARNING: QERApp_GetTwoSelectedPatch failed (did not find two patches)\n");
47 #endif
48   return;
49 }
50
51 // Nurail: The following functions are used by the Surface Inspector module
52
53 // Queries the number of faces from selected brushes
54 int SI_GetSelectedFaceCountfromBrushes(void)
55 {
56   face_t        *f;
57   brush_t       *b;
58   int           num_of_faces = 0;
59
60   if(selected_brushes.next == &selected_brushes)
61     return(0);
62
63   for(b=selected_brushes.next; b!=&selected_brushes; b=b->next)
64     if (!(b->patchBrush))
65       for(f=b->brush_faces; f ; f=f->next, num_of_faces++);
66
67   return num_of_faces;
68 }
69
70 void SI_GetSelFacesTexdef(texdef_to_face_t *allocd_block_texdef)
71 {
72   int           i;
73   face_t        *f;
74   brush_t       *b;
75   texdef_to_face_t *position, *prev_pos;
76
77   if(selected_brushes.next != &selected_brushes)
78   {
79     prev_pos = position = allocd_block_texdef;
80     for(b=selected_brushes.next; b!=&selected_brushes; b=b->next)
81     {
82       if ( !(b->patchBrush) )
83       {
84         for(f=b->brush_faces; f ; f = f->next)
85         {
86             position->face = f;
87             position->brush = b;
88             position->texdef = f->texdef;
89             position->orig_texdef = f->texdef;
90             prev_pos->next = position;
91             prev_pos = position;
92             position++;
93               }
94               prev_pos->next = NULL;
95       }
96     }
97   }
98   else if(g_ptrSelectedFaces.GetSize() != 0)
99   {
100     f = (face_t *) g_ptrSelectedFaces.GetAt(0);
101     b = (brush_t *) g_ptrSelectedFaceBrushes.GetAt(0);
102     position = (texdef_to_face_t*) allocd_block_texdef;
103     position->face = f;
104     position->brush = b;
105     position->texdef = f->texdef;
106     position->orig_texdef = f->texdef;
107     prev_pos = position;
108     for(i=1; i<g_ptrSelectedFaces.GetSize(); i++)
109     {
110       f = (face_t *) g_ptrSelectedFaces.GetAt(i);
111       b = (brush_t *) g_ptrSelectedFaceBrushes.GetAt(i);
112       position = allocd_block_texdef + i;
113       position->face = f;
114       position->brush = b;
115       position->texdef = f->texdef;
116       position->orig_texdef = f->texdef;
117       prev_pos->next = position;
118       prev_pos = position;
119     }
120     position->next = NULL;
121   }
122
123 }
124
125 /*
126 SetFaceTexdef_Q2
127
128 This doesn't mess with CONTENTS_DETAIL needed for Quake2 content flag
129
130 */
131 void SetFaceTexdef_Q2 (face_t *f, texdef_t *texdef, bool bFitScale)
132 {
133
134   if(strcmp(f->texdef.GetName(), texdef->GetName()) != 0) // set shader here instead of Brush_Build
135     Face_SetShader(f, texdef->GetName());
136
137                 if (bFitScale)
138                 {
139                         f->texdef = *texdef;
140                         // fit the scaling of the texture on the actual plane
141                         vec3_t p1,p2,p3; // absolute coordinates
142                         // compute absolute coordinates
143                         ComputeAbsolute(f,p1,p2,p3);
144                         // compute the scale
145                         vec3_t vx,vy;
146                         VectorSubtract(p2,p1,vx);
147                         VectorNormalize(vx, vx);
148                         VectorSubtract(p3,p1,vy);
149                         VectorNormalize(vy, vy);
150                         // assign scale
151                         VectorScale(vx,texdef->scale[0],vx);
152                         VectorScale(vy,texdef->scale[1],vy);
153                         VectorAdd(p1,vx,p2);
154                         VectorAdd(p1,vy,p3);
155                         // compute back shift scale rot
156                         AbsoluteToLocal(f->plane,f,p1,p2,p3);
157                 }
158                 else
159     {
160                         f->texdef = *texdef;
161     }
162   }
163
164
165
166 void SI_SetTexdef_FaceList(texdef_to_face_t* texdef_face_list, bool b_SetUndoPoint, bool bFit_to_Scale)
167 {
168   texdef_to_face_t* texdef_to_face;
169   bool b_isQuake2;
170
171   if ( ( g_pGameDescription->mGameFile == "q2.game" ) || ( g_pGameDescription->mGameFile == "heretic2.game" ) )
172     b_isQuake2 = true;
173   else
174     b_isQuake2 = false;
175
176   if (!texdef_face_list)
177     return;
178     
179  if (b_SetUndoPoint)
180  {
181     if(g_ptrSelectedFaces.GetSize() > 1)
182       Sys_FPrintf(SYS_WRN, "WARNING: Undo NOT supported for multiple face selections\n");
183     else if( (selected_brushes.next != &selected_brushes) || (g_ptrSelectedFaces.GetSize() == 1))
184     {
185       // Give something to undo to
186       for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next)
187       if (b_isQuake2)
188         SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->orig_texdef, bFit_to_Scale);
189       else
190         SetFaceTexdef(texdef_to_face->face, &texdef_to_face->orig_texdef, NULL);
191
192       Undo_Start("set facelist texdefs");
193       
194       if( selected_brushes.next != &selected_brushes )
195         Undo_AddBrushList(&selected_brushes); 
196       else
197         Undo_AddBrush(texdef_face_list->brush);
198       
199     }
200  }  
201     
202   for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next)
203   {
204     if (b_isQuake2)
205       SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->texdef,  bFit_to_Scale);
206     else
207       SetFaceTexdef(texdef_to_face->face, &texdef_to_face->texdef, NULL , bFit_to_Scale);
208     Brush_Build(texdef_to_face->brush); 
209     if(bFit_to_Scale)
210       texdef_to_face->texdef = texdef_to_face->face->texdef;
211   }
212   
213   if ( b_SetUndoPoint )
214   {
215       if( (selected_brushes.next != &selected_brushes) || (g_ptrSelectedFaces.GetSize() == 1) )
216       {
217         if(selected_brushes.next != &selected_brushes)
218           Undo_EndBrushList(&selected_brushes); 
219         else
220           Undo_EndBrush(texdef_face_list->brush);
221           
222         Undo_End();
223         // Over-write the orig_texdef list, cementing the change.
224         for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next)
225           texdef_to_face->orig_texdef = texdef_to_face->texdef;
226       }
227   }
228   
229   Sys_UpdateWindows (W_ALL);
230 }
231
232 void SI_FaceList_FitTexture(texdef_to_face_t* si_texdef_face_list, int nHeight, int nWidth)
233 {
234   texdef_to_face_t* temp_texdef_face_list;
235
236   if (!si_texdef_face_list)
237     return;
238
239   for (temp_texdef_face_list = si_texdef_face_list; temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
240   {
241     Face_FitTexture(temp_texdef_face_list->face, nHeight, nWidth);
242     Brush_Build(temp_texdef_face_list->brush,true,true,false,false); 
243     // Write changes to our working Texdef list
244     temp_texdef_face_list->texdef = temp_texdef_face_list->face->texdef;
245   }
246
247   Sys_UpdateWindows (W_CAMERA);
248
249 }
250
251 GtkWindow* SI_GetMainWindow(void)
252 {
253   return GTK_WINDOW(g_qeglobals_gui.d_main_window);
254 }
255
256 void SI_SetWinPos_from_Prefs(GtkWidget *win)
257 {
258   load_window_pos (win, g_PrefsDlg.mWindowInfo.posSurfaceWnd);
259 }