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