]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/brushmodule.cpp
ported bobtoolz
[xonotic/netradiant.git] / radiant / brushmodule.cpp
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
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 #include "brushmodule.h"
23
24 #include "qerplugin.h"
25
26 #include "brushnode.h"
27 #include "brushmanip.h"
28
29 #include "preferencesystem.h"
30 #include "stringio.h"
31
32 #include "map.h"
33 #include "qe3.h"
34 #include "mainframe.h"
35 #include "preferences.h"
36
37 LatchedBool g_useAlternativeTextureProjection(false, "Use alternative texture-projection");
38 bool g_showAlternativeTextureProjectionOption = false;
39
40 bool getTextureLockEnabled()
41 {
42   return g_brush_texturelock_enabled;
43 }
44
45 void Face_importSnapPlanes(bool value)
46 {
47   Face::m_quantise = value ? quantiseInteger : quantiseFloating;
48 }
49 typedef FreeCaller1<bool, Face_importSnapPlanes> FaceImportSnapPlanesCaller;
50
51 void Face_exportSnapPlanes(const BoolImportCallback& importer)
52 {
53   importer(Face::m_quantise == quantiseInteger);
54 }
55 typedef FreeCaller1<const BoolImportCallback&, Face_exportSnapPlanes> FaceExportSnapPlanesCaller;
56
57 void Brush_constructPreferences(PreferencesPage& page)
58 {
59   page.appendCheckBox(
60     "", "Snap planes to integer grid",
61     FaceImportSnapPlanesCaller(),
62     FaceExportSnapPlanesCaller()
63   );
64   page.appendEntry(
65     "Default texture scale",
66     g_texdef_default_scale
67   );
68   if(g_showAlternativeTextureProjectionOption)
69   {
70     page.appendCheckBox(
71       "", "Use alternative texture-projection",
72       LatchedBoolImportCaller(g_useAlternativeTextureProjection),
73       BoolExportCaller(g_useAlternativeTextureProjection.m_latched)
74     );
75   }
76 }
77 void Brush_constructPage(PreferenceGroup& group)
78 {
79   PreferencesPage page(group.createPage("Brush", "Brush Settings"));
80   Brush_constructPreferences(page);
81 }
82 void Brush_registerPreferencesPage()
83 {
84   PreferencesDialog_addSettingsPage(FreeCaller1<PreferenceGroup&, Brush_constructPage>());
85 }
86
87
88 void Brush_Construct(EBrushType type)
89 {
90   if(type == eBrushTypeQuake3)
91   {
92     g_showAlternativeTextureProjectionOption = true;
93
94     GlobalPreferenceSystem().registerPreference(
95       "AlternativeTextureProjection",
96       BoolImportStringCaller(g_useAlternativeTextureProjection.m_latched),
97       BoolExportStringCaller(g_useAlternativeTextureProjection.m_latched)
98     );
99     g_useAlternativeTextureProjection.useLatched();
100
101     if(g_useAlternativeTextureProjection.m_value)
102     {
103       type = eBrushTypeQuake3BP;
104     }
105   }
106
107   Brush_registerCommands();
108   Brush_registerPreferencesPage();
109
110   BrushFilters_construct();
111
112   BrushClipPlane::constructStatic();
113   BrushInstance::constructStatic();
114   Brush::constructStatic(type);
115
116   Brush::m_maxWorldCoord = g_MaxWorldCoord;
117   BrushInstance::m_counter = &g_brushCount;
118
119   g_texdef_default_scale = 0.5f;
120   const char* value = g_pGameDescription->getKeyValue("default_scale");
121   if(!string_empty(value))
122   {
123     float scale = static_cast<float>(atof(value));
124     if(scale != 0)
125     {
126       g_texdef_default_scale = scale;
127     }
128     else
129     {
130       globalErrorStream() << "error parsing \"default_scale\" attribute\n";
131     }
132   }
133
134   FaceTextureClipboard_setDefault();
135
136   GlobalPreferenceSystem().registerPreference("TextureLock", BoolImportStringCaller(g_brush_texturelock_enabled), BoolExportStringCaller(g_brush_texturelock_enabled));
137   GlobalPreferenceSystem().registerPreference("BrushSnapPlanes", makeBoolStringImportCallback(FaceImportSnapPlanesCaller()), makeBoolStringExportCallback(FaceExportSnapPlanesCaller()));
138   GlobalPreferenceSystem().registerPreference("TexdefDefaultScale", FloatImportStringCaller(g_texdef_default_scale), FloatExportStringCaller(g_texdef_default_scale));
139
140   GridStatus_getTextureLockEnabled = getTextureLockEnabled;
141   g_texture_lock_status_changed = FreeCaller<GridStatus_onTextureLockEnabledChanged>();
142 }
143
144 void Brush_Destroy()
145 {
146   Brush::m_maxWorldCoord = 0;
147   BrushInstance::m_counter = 0;
148
149   Brush::destroyStatic();
150   BrushInstance::destroyStatic();
151   BrushClipPlane::destroyStatic();
152 }
153
154 void Brush_clipperColourChanged()
155 {
156   BrushClipPlane::destroyStatic();
157   BrushClipPlane::constructStatic();
158 }
159
160 void BrushFaceData_fromFace(const BrushFaceDataCallback& callback, Face& face)
161 {
162   _QERFaceData faceData;
163   faceData.m_p0 = face.getPlane().planePoints()[0];
164   faceData.m_p1 = face.getPlane().planePoints()[1];
165   faceData.m_p2 = face.getPlane().planePoints()[2];
166   faceData.m_shader = face.GetShader();
167   faceData.m_texdef = face.getTexdef().m_projection.m_texdef;
168   faceData.contents = face.getShader().m_flags.m_contentFlags;
169   faceData.flags = face.getShader().m_flags.m_surfaceFlags;
170   faceData.value = face.getShader().m_flags.m_value;
171   callback(faceData);
172 }
173 typedef ConstReferenceCaller1<BrushFaceDataCallback, Face&, BrushFaceData_fromFace> BrushFaceDataFromFaceCaller;
174 typedef Callback1<Face&> FaceCallback;
175
176 class Quake3BrushCreator : public BrushCreator
177 {
178 public:
179   scene::Node& createBrush()
180   {
181     return (new BrushNode)->node();
182   }
183   bool useAlternativeTextureProjection() const
184   {
185     return g_useAlternativeTextureProjection.m_value;
186   }
187   void Brush_forEachFace(scene::Node& brush, const BrushFaceDataCallback& callback)
188   {
189     ::Brush_forEachFace(*Node_getBrush(brush), FaceCallback(BrushFaceDataFromFaceCaller(callback)));
190   }
191   bool Brush_addFace(scene::Node& brush, const _QERFaceData& faceData)
192   {
193     Node_getBrush(brush)->undoSave();
194     return Node_getBrush(brush)->addPlane(faceData.m_p0, faceData.m_p1, faceData.m_p2, faceData.m_shader, TextureProjection(faceData.m_texdef, brushprimit_texdef_t(), Vector3(0, 0, 0), Vector3(0, 0, 0))) != 0;
195   }
196 };
197
198 Quake3BrushCreator g_Quake3BrushCreator;
199
200 BrushCreator& GetBrushCreator()
201 {
202   return g_Quake3BrushCreator;
203 }
204
205 #include "modulesystem/singletonmodule.h"
206 #include "modulesystem/moduleregistry.h"
207
208
209 class BrushDependencies :
210   public GlobalRadiantModuleRef,
211   public GlobalSceneGraphModuleRef,
212   public GlobalShaderCacheModuleRef,
213   public GlobalSelectionModuleRef,
214   public GlobalOpenGLModuleRef,
215   public GlobalUndoModuleRef,
216   public GlobalFilterModuleRef
217 {
218 };
219
220 class BrushDoom3API : public TypeSystemRef
221 {
222   BrushCreator* m_brushdoom3;
223 public:
224   typedef BrushCreator Type;
225   STRING_CONSTANT(Name, "doom3");
226
227   BrushDoom3API()
228   {
229     Brush_Construct(eBrushTypeDoom3);
230
231      m_brushdoom3 = &GetBrushCreator();
232   }
233   ~BrushDoom3API()
234   {
235     Brush_Destroy();
236   }
237   BrushCreator* getTable()
238   {
239     return m_brushdoom3;
240   }
241 };
242
243 typedef SingletonModule<BrushDoom3API, BrushDependencies> BrushDoom3Module;
244 typedef Static<BrushDoom3Module> StaticBrushDoom3Module;
245 StaticRegisterModule staticRegisterBrushDoom3(StaticBrushDoom3Module::instance());
246
247
248 class BrushQuake4API : public TypeSystemRef
249 {
250   BrushCreator* m_brushquake4;
251 public:
252   typedef BrushCreator Type;
253   STRING_CONSTANT(Name, "quake4");
254
255   BrushQuake4API()
256   {
257     Brush_Construct(eBrushTypeQuake4);
258
259      m_brushquake4 = &GetBrushCreator();
260   }
261   ~BrushQuake4API()
262   {
263     Brush_Destroy();
264   }
265   BrushCreator* getTable()
266   {
267     return m_brushquake4;
268   }
269 };
270
271 typedef SingletonModule<BrushQuake4API, BrushDependencies> BrushQuake4Module;
272 typedef Static<BrushQuake4Module> StaticBrushQuake4Module;
273 StaticRegisterModule staticRegisterBrushQuake4(StaticBrushQuake4Module::instance());
274
275
276 class BrushQuake3API : public TypeSystemRef
277 {
278   BrushCreator* m_brushquake3;
279 public:
280   typedef BrushCreator Type;
281   STRING_CONSTANT(Name, "quake3");
282
283   BrushQuake3API()
284   {
285     Brush_Construct(eBrushTypeQuake3);
286
287     m_brushquake3 = &GetBrushCreator();
288   }
289   ~BrushQuake3API()
290   {
291     Brush_Destroy();
292   }
293   BrushCreator* getTable()
294   {
295     return m_brushquake3;
296   }
297 };
298
299 typedef SingletonModule<BrushQuake3API, BrushDependencies> BrushQuake3Module;
300 typedef Static<BrushQuake3Module> StaticBrushQuake3Module;
301 StaticRegisterModule staticRegisterBrushQuake3(StaticBrushQuake3Module::instance());
302
303
304 class BrushQuake2API : public TypeSystemRef
305 {
306   BrushCreator* m_brushquake2;
307 public:
308   typedef BrushCreator Type;
309   STRING_CONSTANT(Name, "quake2");
310
311   BrushQuake2API()
312   {
313     Brush_Construct(eBrushTypeQuake2);
314
315     m_brushquake2 = &GetBrushCreator();
316   }
317   ~BrushQuake2API()
318   {
319     Brush_Destroy();
320   }
321   BrushCreator* getTable()
322   {
323     return m_brushquake2;
324   }
325 };
326
327 typedef SingletonModule<BrushQuake2API, BrushDependencies> BrushQuake2Module;
328 typedef Static<BrushQuake2Module> StaticBrushQuake2Module;
329 StaticRegisterModule staticRegisterBrushQuake2(StaticBrushQuake2Module::instance());
330
331
332 class BrushQuake1API : public TypeSystemRef
333 {
334   BrushCreator* m_brushquake1;
335 public:
336   typedef BrushCreator Type;
337   STRING_CONSTANT(Name, "quake");
338
339   BrushQuake1API()
340   {
341     Brush_Construct(eBrushTypeQuake);
342
343     m_brushquake1 = &GetBrushCreator();
344   }
345   ~BrushQuake1API()
346   {
347     Brush_Destroy();
348   }
349   BrushCreator* getTable()
350   {
351     return m_brushquake1;
352   }
353 };
354
355 typedef SingletonModule<BrushQuake1API, BrushDependencies> BrushQuake1Module;
356 typedef Static<BrushQuake1Module> StaticBrushQuake1Module;
357 StaticRegisterModule staticRegisterBrushQuake1(StaticBrushQuake1Module::instance());
358
359
360 class BrushHalfLifeAPI : public TypeSystemRef
361 {
362   BrushCreator* m_brushhalflife;
363 public:
364   typedef BrushCreator Type;
365   STRING_CONSTANT(Name, "halflife");
366
367   BrushHalfLifeAPI()
368   {
369     Brush_Construct(eBrushTypeHalfLife);
370
371     m_brushhalflife = &GetBrushCreator();
372   }
373   ~BrushHalfLifeAPI()
374   {
375     Brush_Destroy();
376   }
377   BrushCreator* getTable()
378   {
379     return m_brushhalflife;
380   }
381 };
382
383 typedef SingletonModule<BrushHalfLifeAPI, BrushDependencies> BrushHalfLifeModule;
384 typedef Static<BrushHalfLifeModule> StaticBrushHalfLifeModule;
385 StaticRegisterModule staticRegisterBrushHalfLife(StaticBrushHalfLifeModule::instance());