2 Copyright (C) 2001-2006, William Joseph.
5 This file is part of GtkRadiant.
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.
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.
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
22 #include "brushmodule.h"
24 #include "qerplugin.h"
26 #include "brushnode.h"
27 #include "brushmanip.h"
29 #include "preferencesystem.h"
34 #include "mainframe.h"
35 #include "preferences.h"
37 LatchedBool g_useAlternativeTextureProjection(false, "Use alternative texture-projection");
38 bool g_showAlternativeTextureProjectionOption = false;
39 bool g_brush_always_caulk;
41 bool getTextureLockEnabled()
43 return g_brush_texturelock_enabled;
46 void Face_importSnapPlanes(bool value)
48 Face::m_quantise = value ? quantiseInteger : quantiseFloating;
50 typedef FreeCaller1<bool, Face_importSnapPlanes> FaceImportSnapPlanesCaller;
52 void Face_exportSnapPlanes(const BoolImportCallback& importer)
54 importer(Face::m_quantise == quantiseInteger);
56 typedef FreeCaller1<const BoolImportCallback&, Face_exportSnapPlanes> FaceExportSnapPlanesCaller;
58 void Brush_constructPreferences(PreferencesPage& page)
61 "", "Snap planes to integer grid",
62 FaceImportSnapPlanesCaller(),
63 FaceExportSnapPlanesCaller()
66 "Default texture scale",
67 g_texdef_default_scale
69 if(g_showAlternativeTextureProjectionOption)
72 "", "Use alternative texture-projection",
73 LatchedBoolImportCaller(g_useAlternativeTextureProjection),
74 BoolExportCaller(g_useAlternativeTextureProjection.m_latched)
78 page.appendCheckBox("",
79 "Always use caulk for new brushes",
83 void Brush_constructPage(PreferenceGroup& group)
85 PreferencesPage page(group.createPage("Brush", "Brush Settings"));
86 Brush_constructPreferences(page);
88 void Brush_registerPreferencesPage()
90 PreferencesDialog_addSettingsPage(FreeCaller1<PreferenceGroup&, Brush_constructPage>());
93 void Brush_unlatchPreferences()
95 Brush_toggleFormat(0);
98 void Brush_toggleFormat(int i)
100 if(g_showAlternativeTextureProjectionOption)
102 g_useAlternativeTextureProjection.m_value = g_useAlternativeTextureProjection.m_latched ^ i;
103 Brush::destroyStatic();
104 Brush::constructStatic(g_useAlternativeTextureProjection.m_value ? eBrushTypeQuake3BP : eBrushTypeQuake3);
108 int Brush_toggleFormatCount()
110 if(g_showAlternativeTextureProjectionOption)
115 void Brush_Construct(EBrushType type)
117 if(type == eBrushTypeQuake3)
119 g_showAlternativeTextureProjectionOption = true;
121 const char *value = g_pGameDescription->getKeyValue("brush_primit");
122 if(!string_empty(value))
123 g_useAlternativeTextureProjection.m_latched = atoi(value);
125 GlobalPreferenceSystem().registerPreference(
126 "AlternativeTextureProjection",
127 BoolImportStringCaller(g_useAlternativeTextureProjection.m_latched),
128 BoolExportStringCaller(g_useAlternativeTextureProjection.m_latched)
130 g_useAlternativeTextureProjection.useLatched();
132 if(g_useAlternativeTextureProjection.m_value)
134 type = eBrushTypeQuake3BP;
138 GlobalPreferenceSystem().registerPreference(
140 BoolImportStringCaller(g_brush_always_caulk),
141 BoolExportStringCaller(g_brush_always_caulk));
144 Brush_registerCommands();
145 Brush_registerPreferencesPage();
147 BrushFilters_construct();
149 BrushClipPlane::constructStatic();
150 BrushInstance::constructStatic();
151 Brush::constructStatic(type);
153 Brush::m_maxWorldCoord = g_MaxWorldCoord;
154 BrushInstance::m_counter = &g_brushCount;
156 g_texdef_default_scale = 0.5f;
157 const char* value = g_pGameDescription->getKeyValue("default_scale");
158 if(!string_empty(value))
160 float scale = static_cast<float>(atof(value));
163 g_texdef_default_scale = scale;
167 globalErrorStream() << "error parsing \"default_scale\" attribute\n";
171 GlobalPreferenceSystem().registerPreference("TextureLock", BoolImportStringCaller(g_brush_texturelock_enabled), BoolExportStringCaller(g_brush_texturelock_enabled));
172 GlobalPreferenceSystem().registerPreference("BrushSnapPlanes", makeBoolStringImportCallback(FaceImportSnapPlanesCaller()), makeBoolStringExportCallback(FaceExportSnapPlanesCaller()));
173 GlobalPreferenceSystem().registerPreference("TexdefDefaultScale", FloatImportStringCaller(g_texdef_default_scale), FloatExportStringCaller(g_texdef_default_scale));
175 GridStatus_getTextureLockEnabled = getTextureLockEnabled;
176 g_texture_lock_status_changed = FreeCaller<GridStatus_onTextureLockEnabledChanged>();
181 Brush::m_maxWorldCoord = 0;
182 BrushInstance::m_counter = 0;
184 Brush::destroyStatic();
185 BrushInstance::destroyStatic();
186 BrushClipPlane::destroyStatic();
189 void Brush_clipperColourChanged()
191 BrushClipPlane::destroyStatic();
192 BrushClipPlane::constructStatic();
195 void BrushFaceData_fromFace(const BrushFaceDataCallback& callback, Face& face)
197 _QERFaceData faceData;
198 faceData.m_p0 = face.getPlane().planePoints()[0];
199 faceData.m_p1 = face.getPlane().planePoints()[1];
200 faceData.m_p2 = face.getPlane().planePoints()[2];
201 faceData.m_shader = face.GetShader();
202 faceData.m_texdef = face.getTexdef().m_projection.m_texdef;
203 faceData.contents = face.getShader().m_flags.m_contentFlags;
204 faceData.flags = face.getShader().m_flags.m_surfaceFlags;
205 faceData.value = face.getShader().m_flags.m_value;
208 typedef ConstReferenceCaller1<BrushFaceDataCallback, Face&, BrushFaceData_fromFace> BrushFaceDataFromFaceCaller;
209 typedef Callback1<Face&> FaceCallback;
211 class Quake3BrushCreator : public BrushCreator
214 scene::Node& createBrush()
216 return (new BrushNode)->node();
218 bool useAlternativeTextureProjection() const
220 return g_useAlternativeTextureProjection.m_value;
222 void Brush_forEachFace(scene::Node& brush, const BrushFaceDataCallback& callback)
224 ::Brush_forEachFace(*Node_getBrush(brush), FaceCallback(BrushFaceDataFromFaceCaller(callback)));
226 bool Brush_addFace(scene::Node& brush, const _QERFaceData& faceData)
228 Node_getBrush(brush)->undoSave();
229 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;
233 Quake3BrushCreator g_Quake3BrushCreator;
235 BrushCreator& GetBrushCreator()
237 return g_Quake3BrushCreator;
240 #include "modulesystem/singletonmodule.h"
241 #include "modulesystem/moduleregistry.h"
244 class BrushDependencies :
245 public GlobalRadiantModuleRef,
246 public GlobalSceneGraphModuleRef,
247 public GlobalShaderCacheModuleRef,
248 public GlobalSelectionModuleRef,
249 public GlobalOpenGLModuleRef,
250 public GlobalUndoModuleRef,
251 public GlobalFilterModuleRef
255 class BrushDoom3API : public TypeSystemRef
257 BrushCreator* m_brushdoom3;
259 typedef BrushCreator Type;
260 STRING_CONSTANT(Name, "doom3");
264 Brush_Construct(eBrushTypeDoom3);
266 m_brushdoom3 = &GetBrushCreator();
272 BrushCreator* getTable()
278 typedef SingletonModule<BrushDoom3API, BrushDependencies> BrushDoom3Module;
279 typedef Static<BrushDoom3Module> StaticBrushDoom3Module;
280 StaticRegisterModule staticRegisterBrushDoom3(StaticBrushDoom3Module::instance());
283 class BrushQuake4API : public TypeSystemRef
285 BrushCreator* m_brushquake4;
287 typedef BrushCreator Type;
288 STRING_CONSTANT(Name, "quake4");
292 Brush_Construct(eBrushTypeQuake4);
294 m_brushquake4 = &GetBrushCreator();
300 BrushCreator* getTable()
302 return m_brushquake4;
306 typedef SingletonModule<BrushQuake4API, BrushDependencies> BrushQuake4Module;
307 typedef Static<BrushQuake4Module> StaticBrushQuake4Module;
308 StaticRegisterModule staticRegisterBrushQuake4(StaticBrushQuake4Module::instance());
311 class BrushQuake3API : public TypeSystemRef
313 BrushCreator* m_brushquake3;
315 typedef BrushCreator Type;
316 STRING_CONSTANT(Name, "quake3");
320 Brush_Construct(eBrushTypeQuake3);
322 m_brushquake3 = &GetBrushCreator();
328 BrushCreator* getTable()
330 return m_brushquake3;
334 typedef SingletonModule<BrushQuake3API, BrushDependencies> BrushQuake3Module;
335 typedef Static<BrushQuake3Module> StaticBrushQuake3Module;
336 StaticRegisterModule staticRegisterBrushQuake3(StaticBrushQuake3Module::instance());
339 class BrushQuake2API : public TypeSystemRef
341 BrushCreator* m_brushquake2;
343 typedef BrushCreator Type;
344 STRING_CONSTANT(Name, "quake2");
348 Brush_Construct(eBrushTypeQuake2);
350 m_brushquake2 = &GetBrushCreator();
356 BrushCreator* getTable()
358 return m_brushquake2;
362 typedef SingletonModule<BrushQuake2API, BrushDependencies> BrushQuake2Module;
363 typedef Static<BrushQuake2Module> StaticBrushQuake2Module;
364 StaticRegisterModule staticRegisterBrushQuake2(StaticBrushQuake2Module::instance());
367 class BrushQuake1API : public TypeSystemRef
369 BrushCreator* m_brushquake1;
371 typedef BrushCreator Type;
372 STRING_CONSTANT(Name, "quake");
376 Brush_Construct(eBrushTypeQuake);
378 m_brushquake1 = &GetBrushCreator();
384 BrushCreator* getTable()
386 return m_brushquake1;
390 typedef SingletonModule<BrushQuake1API, BrushDependencies> BrushQuake1Module;
391 typedef Static<BrushQuake1Module> StaticBrushQuake1Module;
392 StaticRegisterModule staticRegisterBrushQuake1(StaticBrushQuake1Module::instance());
395 class BrushHalfLifeAPI : public TypeSystemRef
397 BrushCreator* m_brushhalflife;
399 typedef BrushCreator Type;
400 STRING_CONSTANT(Name, "halflife");
404 Brush_Construct(eBrushTypeHalfLife);
406 m_brushhalflife = &GetBrushCreator();
412 BrushCreator* getTable()
414 return m_brushhalflife;
418 typedef SingletonModule<BrushHalfLifeAPI, BrushDependencies> BrushHalfLifeModule;
419 typedef Static<BrushHalfLifeModule> StaticBrushHalfLifeModule;
420 StaticRegisterModule staticRegisterBrushHalfLife(StaticBrushHalfLifeModule::instance());