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 LatchedValue<bool> g_useAlternativeTextureProjection(false,
38 "Use alternative texture-projection (\"brush primitives\")");
39 bool g_showAlternativeTextureProjectionOption = false;
40 bool g_brush_always_caulk;
42 bool getTextureLockEnabled()
44 return g_brush_texturelock_enabled;
47 struct Face_SnapPlanes {
48 static void Export(const QuantiseFunc &self, const Callback<void(bool)> &returnz)
50 returnz(self == quantiseInteger);
53 static void Import(QuantiseFunc &self, bool value)
55 self = value ? quantiseInteger : quantiseFloating;
59 void Brush_constructPreferences(PreferencesPage &page)
62 "", "Snap planes to integer grid",
63 make_property<Face_SnapPlanes>(Face::m_quantise)
66 "Default texture scale",
67 g_texdef_default_scale
69 if (g_showAlternativeTextureProjectionOption) {
71 "", "Use alternative texture-projection (\"brush primitives\")",
72 make_property(g_useAlternativeTextureProjection)
76 page.appendCheckBox("",
77 "Always use caulk for new brushes",
82 void Brush_constructPage(PreferenceGroup &group)
84 PreferencesPage page(group.createPage("Brush", "Brush Settings"));
85 Brush_constructPreferences(page);
88 void Brush_registerPreferencesPage()
90 PreferencesDialog_addSettingsPage(makeCallbackF(Brush_constructPage));
93 void Brush_unlatchPreferences()
95 Brush_toggleFormat(0);
98 void Brush_toggleFormat(int i)
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);
107 int Brush_toggleFormatCount()
109 if (g_showAlternativeTextureProjectionOption) {
115 void Brush_Construct(EBrushType type)
117 if (type == eBrushTypeQuake3) {
118 g_showAlternativeTextureProjectionOption = true;
120 const char *value = g_pGameDescription->getKeyValue("brush_primit");
121 if (!string_empty(value)) {
122 g_useAlternativeTextureProjection.m_latched = atoi(value);
125 GlobalPreferenceSystem().registerPreference(
126 "AlternativeTextureProjection",
127 make_property_string(g_useAlternativeTextureProjection.m_latched)
129 g_useAlternativeTextureProjection.useLatched();
131 if (g_useAlternativeTextureProjection.m_value) {
132 type = eBrushTypeQuake3BP;
136 GlobalPreferenceSystem().registerPreference(
138 make_property_string(g_brush_always_caulk)
142 Brush_registerCommands();
143 Brush_registerPreferencesPage();
145 BrushFilters_construct();
147 BrushClipPlane::constructStatic();
148 BrushInstance::constructStatic();
149 Brush::constructStatic(type);
151 Brush::m_maxWorldCoord = g_MaxWorldCoord;
152 BrushInstance::m_counter = &g_brushCount;
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));
159 g_texdef_default_scale = scale;
161 globalErrorStream() << "error parsing \"default_scale\" attribute\n";
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));
170 GridStatus_getTextureLockEnabled = getTextureLockEnabled;
171 g_texture_lock_status_changed = makeCallbackF(GridStatus_onTextureLockEnabledChanged);
176 Brush::m_maxWorldCoord = 0;
177 BrushInstance::m_counter = 0;
179 Brush::destroyStatic();
180 BrushInstance::destroyStatic();
181 BrushClipPlane::destroyStatic();
184 void Brush_clipperColourChanged()
186 BrushClipPlane::destroyStatic();
187 BrushClipPlane::constructStatic();
190 void BrushFaceData_fromFace(const BrushFaceDataCallback &callback, Face &face)
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;
204 typedef ConstReferenceCaller<BrushFaceDataCallback, void(Face &), BrushFaceData_fromFace> BrushFaceDataFromFaceCaller;
205 typedef Callback<void(Face &)> FaceCallback;
207 class Quake3BrushCreator : public BrushCreator {
209 scene::Node &createBrush()
211 return (new BrushNode)->node();
214 bool useAlternativeTextureProjection() const
216 return g_useAlternativeTextureProjection.m_value;
219 void Brush_forEachFace(scene::Node &brush, const BrushFaceDataCallback &callback)
221 ::Brush_forEachFace(*Node_getBrush(brush), FaceCallback(BrushFaceDataFromFaceCaller(callback)));
224 bool Brush_addFace(scene::Node &brush, const _QERFaceData &faceData)
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;
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 {
254 class BrushDoom3API : public TypeSystemRef {
255 BrushCreator *m_brushdoom3;
257 typedef BrushCreator Type;
259 STRING_CONSTANT(Name, "doom3");
263 Brush_Construct(eBrushTypeDoom3);
265 m_brushdoom3 = &GetBrushCreator();
273 BrushCreator *getTable()
279 typedef SingletonModule<BrushDoom3API, BrushDependencies> BrushDoom3Module;
280 typedef Static<BrushDoom3Module> StaticBrushDoom3Module;
281 StaticRegisterModule staticRegisterBrushDoom3(StaticBrushDoom3Module::instance());
284 class BrushQuake4API : public TypeSystemRef {
285 BrushCreator *m_brushquake4;
287 typedef BrushCreator Type;
289 STRING_CONSTANT(Name, "quake4");
293 Brush_Construct(eBrushTypeQuake4);
295 m_brushquake4 = &GetBrushCreator();
303 BrushCreator *getTable()
305 return m_brushquake4;
309 typedef SingletonModule<BrushQuake4API, BrushDependencies> BrushQuake4Module;
310 typedef Static<BrushQuake4Module> StaticBrushQuake4Module;
311 StaticRegisterModule staticRegisterBrushQuake4(StaticBrushQuake4Module::instance());
314 class BrushQuake3API : public TypeSystemRef {
315 BrushCreator *m_brushquake3;
317 typedef BrushCreator Type;
319 STRING_CONSTANT(Name, "quake3");
323 Brush_Construct(eBrushTypeQuake3);
325 m_brushquake3 = &GetBrushCreator();
333 BrushCreator *getTable()
335 return m_brushquake3;
339 typedef SingletonModule<BrushQuake3API, BrushDependencies> BrushQuake3Module;
340 typedef Static<BrushQuake3Module> StaticBrushQuake3Module;
341 StaticRegisterModule staticRegisterBrushQuake3(StaticBrushQuake3Module::instance());
344 class BrushQuake2API : public TypeSystemRef {
345 BrushCreator *m_brushquake2;
347 typedef BrushCreator Type;
349 STRING_CONSTANT(Name, "quake2");
353 Brush_Construct(eBrushTypeQuake2);
355 m_brushquake2 = &GetBrushCreator();
363 BrushCreator *getTable()
365 return m_brushquake2;
369 typedef SingletonModule<BrushQuake2API, BrushDependencies> BrushQuake2Module;
370 typedef Static<BrushQuake2Module> StaticBrushQuake2Module;
371 StaticRegisterModule staticRegisterBrushQuake2(StaticBrushQuake2Module::instance());
374 class BrushQuake1API : public TypeSystemRef {
375 BrushCreator *m_brushquake1;
377 typedef BrushCreator Type;
379 STRING_CONSTANT(Name, "quake");
383 Brush_Construct(eBrushTypeQuake);
385 m_brushquake1 = &GetBrushCreator();
393 BrushCreator *getTable()
395 return m_brushquake1;
399 typedef SingletonModule<BrushQuake1API, BrushDependencies> BrushQuake1Module;
400 typedef Static<BrushQuake1Module> StaticBrushQuake1Module;
401 StaticRegisterModule staticRegisterBrushQuake1(StaticBrushQuake1Module::instance());
404 class BrushHalfLifeAPI : public TypeSystemRef {
405 BrushCreator *m_brushhalflife;
407 typedef BrushCreator Type;
409 STRING_CONSTANT(Name, "halflife");
413 Brush_Construct(eBrushTypeHalfLife);
415 m_brushhalflife = &GetBrushCreator();
423 BrushCreator *getTable()
425 return m_brushhalflife;
429 typedef SingletonModule<BrushHalfLifeAPI, BrushDependencies> BrushHalfLifeModule;
430 typedef Static<BrushHalfLifeModule> StaticBrushHalfLifeModule;
431 StaticRegisterModule staticRegisterBrushHalfLife(StaticBrushHalfLifeModule::instance());