From: spog Date: Sat, 13 May 2006 17:15:08 +0000 (+0000) Subject: added patch support for texture-painting X-Git-Tag: xonotic-v0.7.0~16^2~12^2~226 X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=commitdiff_plain;h=f877bbb3ada49ff4884b43175272d0bda3116459 added patch support for texture-painting git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@68 8a3a26a2-13c4-0310-b231-cf6edde360e5 --- diff --git a/CHANGES b/CHANGES index 0ae8162c..f25ae8f0 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,7 @@ SPoG - Fixed crash due to broken module dependencies. - Fixed default settings for Build Monitoring. - Fixed nudge-selection when using the drag tool mode. +- Added support for patches in texture-painting tool. 30/04/2006 SPoG diff --git a/radiant/brushmanip.cpp b/radiant/brushmanip.cpp index 76748797..238a58e9 100644 --- a/radiant/brushmanip.cpp +++ b/radiant/brushmanip.cpp @@ -1362,193 +1362,6 @@ void Texdef_ToggleMoveLock() -void Face_getClosest(Face& face, SelectionTest& test, SelectionIntersection& bestIntersection, Face*& closestFace) -{ - SelectionIntersection intersection; - face.testSelect(test, intersection); - if(intersection.valid() - && SelectionIntersection_closer(intersection, bestIntersection)) - { - bestIntersection = intersection; - closestFace = &face; - } -} - - -class OccludeSelector : public Selector -{ - SelectionIntersection& m_bestIntersection; - bool& m_occluded; -public: - OccludeSelector(SelectionIntersection& bestIntersection, bool& occluded) : m_bestIntersection(bestIntersection), m_occluded(occluded) - { - m_occluded = false; - } - void pushSelectable(Selectable& selectable) - { - } - void popSelectable() - { - } - void addIntersection(const SelectionIntersection& intersection) - { - if(SelectionIntersection_closer(intersection, m_bestIntersection)) - { - m_bestIntersection = intersection; - m_occluded = true; - } - } -}; - -class BrushGetClosestFaceVisibleWalker : public scene::Graph::Walker -{ - SelectionTest& m_test; - Face*& m_closestFace; - mutable SelectionIntersection m_bestIntersection; -public: - BrushGetClosestFaceVisibleWalker(SelectionTest& test, Face*& closestFace) : m_test(test), m_closestFace(closestFace) - { - } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - if(path.top().get().visible()) - { - BrushInstance* brush = Instance_getBrush(instance); - if(brush != 0) - { - m_test.BeginMesh(brush->localToWorld()); - - for(Brush::const_iterator i = brush->getBrush().begin(); i != brush->getBrush().end(); ++i) - { - Face_getClosest(*(*i), m_test, m_bestIntersection, m_closestFace); - } - } - else - { - SelectionTestable* selectionTestable = Instance_getSelectionTestable(instance); - if(selectionTestable) - { - bool occluded; - OccludeSelector selector(m_bestIntersection, occluded); - selectionTestable->testSelect(selector, m_test); - if(occluded) - { - m_closestFace = 0; - } - } - } - } - return true; - } -}; - -Face* Scene_BrushGetClosestFace(scene::Graph& graph, SelectionTest& test) -{ - Face* closestFace = 0; - graph.traverse(BrushGetClosestFaceVisibleWalker(test, closestFace)); - return closestFace; -} - -bool Scene_BrushGetClosestFaceTexture(scene::Graph& graph, SelectionTest& test, CopiedString& shader, TextureProjection& projection, ContentsFlagsValue& flags) -{ - Face* face = Scene_BrushGetClosestFace(graph, test); - if(face != 0) - { - shader = face->GetShader(); - face->GetTexdef(projection); - flags = face->getShader().m_flags; - return true; - } - return false; -} - -void Scene_BrushSetClosestFaceTexture(scene::Graph& graph, SelectionTest& test, const char* shader, const TextureProjection& projection, const ContentsFlagsValue& flags) -{ - Face* face = Scene_BrushGetClosestFace(graph, test); - if(face != 0) - { - face->SetShader(shader); - face->SetTexdef(projection); - face->SetFlags(flags); - } -} - - -class FaceTexture -{ -public: - TextureProjection m_projection; - ContentsFlagsValue m_flags; -}; - -FaceTexture g_faceTextureClipboard; - -void FaceTextureClipboard_setDefault() -{ - g_faceTextureClipboard.m_flags = ContentsFlagsValue(0, 0, 0, false); - TexDef_Construct_Default(g_faceTextureClipboard.m_projection); -} - -void TextureClipboard_textureSelected(const char* shader) -{ - FaceTextureClipboard_setDefault(); -} - -class TextureBrowser; -extern TextureBrowser g_TextureBrowser; -void TextureBrowser_SetSelectedShader(TextureBrowser& textureBrowser, const char* shader); -const char* TextureBrowser_GetSelectedShader(TextureBrowser& textureBrowser); - -void Scene_copyClosestFaceTexture(SelectionTest& test) -{ - CopiedString shader; - if(Scene_BrushGetClosestFaceTexture(GlobalSceneGraph(), test, shader, g_faceTextureClipboard.m_projection, g_faceTextureClipboard.m_flags)) - { - TextureBrowser_SetSelectedShader(g_TextureBrowser, shader.c_str()); - } -} - -void Scene_applyClosestFaceTexture(SelectionTest& test) -{ - UndoableCommand command("facePaintTexture"); - - Scene_BrushSetClosestFaceTexture(GlobalSceneGraph(), test, TextureBrowser_GetSelectedShader(g_TextureBrowser), g_faceTextureClipboard.m_projection, g_faceTextureClipboard.m_flags); - - SceneChangeNotify(); -} - - - -void SelectedFaces_copyTexture() -{ - if(!g_SelectedFaceInstances.empty()) - { - Face& face = g_SelectedFaceInstances.last().getFace(); - face.GetTexdef(g_faceTextureClipboard.m_projection); - g_faceTextureClipboard.m_flags = face.getShader().m_flags; - - TextureBrowser_SetSelectedShader(g_TextureBrowser, face.getShader().getShader()); - } -} - -void FaceInstance_pasteTexture(FaceInstance& faceInstance) -{ - faceInstance.getFace().SetTexdef(g_faceTextureClipboard.m_projection); - faceInstance.getFace().SetShader(TextureBrowser_GetSelectedShader(g_TextureBrowser)); - faceInstance.getFace().SetFlags(g_faceTextureClipboard.m_flags); - SceneChangeNotify(); -} - -bool SelectedFaces_empty() -{ - return g_SelectedFaceInstances.empty(); -} - -void SelectedFaces_pasteTexture() -{ - UndoableCommand command("facePasteTexture"); - g_SelectedFaceInstances.foreach(FaceInstance_pasteTexture); -} void Brush_registerCommands() { @@ -1570,9 +1383,6 @@ void Brush_registerCommands() GlobalCommands_insert("SplitSelected", FreeCaller(), Accelerator(GDK_Return, (GdkModifierType)GDK_SHIFT_MASK)); GlobalCommands_insert("FlipClip", FreeCaller(), Accelerator(GDK_Return, (GdkModifierType)GDK_CONTROL_MASK)); - GlobalCommands_insert("FaceCopyTexture", FreeCaller()); - GlobalCommands_insert("FacePasteTexture", FreeCaller()); - GlobalCommands_insert("MakeDetail", FreeCaller(), Accelerator('M', (GdkModifierType)GDK_CONTROL_MASK)); GlobalCommands_insert("MakeStructural", FreeCaller(), Accelerator('S', (GdkModifierType)(GDK_SHIFT_MASK|GDK_CONTROL_MASK))); } diff --git a/radiant/brushmanip.h b/radiant/brushmanip.h index 2c5cb951..65d95a11 100644 --- a/radiant/brushmanip.h +++ b/radiant/brushmanip.h @@ -74,11 +74,6 @@ void Brush_constructMenu(GtkMenu* menu); extern Callback g_texture_lock_status_changed; -bool SelectedFaces_empty(); -void SelectedFaces_copyTexture(); -void SelectedFaces_pasteTexture(); -void FaceTextureClipboard_setDefault(); - void BrushFilters_construct(); void Brush_registerCommands(); diff --git a/radiant/brushmodule.cpp b/radiant/brushmodule.cpp index cbc4c0a2..66e7a310 100644 --- a/radiant/brushmodule.cpp +++ b/radiant/brushmodule.cpp @@ -131,8 +131,6 @@ void Brush_Construct(EBrushType type) } } - FaceTextureClipboard_setDefault(); - GlobalPreferenceSystem().registerPreference("TextureLock", BoolImportStringCaller(g_brush_texturelock_enabled), BoolExportStringCaller(g_brush_texturelock_enabled)); GlobalPreferenceSystem().registerPreference("BrushSnapPlanes", makeBoolStringImportCallback(FaceImportSnapPlanesCaller()), makeBoolStringExportCallback(FaceExportSnapPlanesCaller())); GlobalPreferenceSystem().registerPreference("TexdefDefaultScale", FloatImportStringCaller(g_texdef_default_scale), FloatExportStringCaller(g_texdef_default_scale)); diff --git a/radiant/selection.cpp b/radiant/selection.cpp index effdfd3c..ed3e973d 100644 --- a/radiant/selection.cpp +++ b/radiant/selection.cpp @@ -3987,8 +3987,8 @@ public: typedef MemberCaller1 MouseUpCaller; }; -void Scene_copyClosestFaceTexture(SelectionTest& test); -void Scene_applyClosestFaceTexture(SelectionTest& test); +void Scene_copyClosestTexture(SelectionTest& test); +void Scene_applyClosestTexture(SelectionTest& test); class RadiantWindowObserver : public SelectionSystemWindowObserver { @@ -4058,11 +4058,11 @@ public: if(modifiers == c_modifier_apply_texture) { - Scene_applyClosestFaceTexture(volume); + Scene_applyClosestTexture(volume); } else if(modifiers == c_modifier_copy_texture) { - Scene_copyClosestFaceTexture(volume); + Scene_copyClosestTexture(volume); } } } diff --git a/radiant/surfacedialog.cpp b/radiant/surfacedialog.cpp index 1ec06951..89785bb7 100644 --- a/radiant/surfacedialog.cpp +++ b/radiant/surfacedialog.cpp @@ -1310,6 +1310,247 @@ void SurfaceInspector::ApplyFlags() Select_SetFlags(ContentsFlagsValue(surfaceflags, contentflags, value, true)); } + +void Face_getTexture(Face& face, CopiedString& shader, TextureProjection& projection, ContentsFlagsValue& flags) +{ + shader = face.GetShader(); + face.GetTexdef(projection); + flags = face.getShader().m_flags; +} +typedef Function4 FaceGetTexture; + +void Face_setTexture(Face& face, const char* shader, const TextureProjection& projection, const ContentsFlagsValue& flags) +{ + face.SetShader(shader); + face.SetTexdef(projection); + face.SetFlags(flags); +} +typedef Function4 FaceSetTexture; + + +void Patch_getTexture(Patch& patch, CopiedString& shader, TextureProjection& projection, ContentsFlagsValue& flags) +{ + shader = patch.GetShader(); + projection = TextureProjection(texdef_t(), brushprimit_texdef_t(), Vector3(0, 0, 0), Vector3(0, 0, 0)); + flags = ContentsFlagsValue(0, 0, 0, false); +} +typedef Function4 PatchGetTexture; + +void Patch_setTexture(Patch& patch, const char* shader, const TextureProjection& projection, const ContentsFlagsValue& flags) +{ + patch.SetShader(shader); +} +typedef Function4 PatchSetTexture; + + +typedef Callback3 GetTextureCallback; +typedef Callback3 SetTextureCallback; + +struct Texturable +{ + GetTextureCallback getTexture; + SetTextureCallback setTexture; +}; + + +void Face_getClosest(Face& face, SelectionTest& test, SelectionIntersection& bestIntersection, Texturable& texturable) +{ + SelectionIntersection intersection; + face.testSelect(test, intersection); + if(intersection.valid() + && SelectionIntersection_closer(intersection, bestIntersection)) + { + bestIntersection = intersection; + texturable.setTexture = makeCallback3(FaceSetTexture(), face); + texturable.getTexture = makeCallback3(FaceGetTexture(), face); + } +} + + +class OccludeSelector : public Selector +{ + SelectionIntersection& m_bestIntersection; + bool& m_occluded; +public: + OccludeSelector(SelectionIntersection& bestIntersection, bool& occluded) : m_bestIntersection(bestIntersection), m_occluded(occluded) + { + m_occluded = false; + } + void pushSelectable(Selectable& selectable) + { + } + void popSelectable() + { + } + void addIntersection(const SelectionIntersection& intersection) + { + if(SelectionIntersection_closer(intersection, m_bestIntersection)) + { + m_bestIntersection = intersection; + m_occluded = true; + } + } +}; + +class BrushGetClosestFaceVisibleWalker : public scene::Graph::Walker +{ + SelectionTest& m_test; + Texturable& m_texturable; + mutable SelectionIntersection m_bestIntersection; +public: + BrushGetClosestFaceVisibleWalker(SelectionTest& test, Texturable& texturable) : m_test(test), m_texturable(texturable) + { + } + bool pre(const scene::Path& path, scene::Instance& instance) const + { + if(path.top().get().visible()) + { + BrushInstance* brush = Instance_getBrush(instance); + if(brush != 0) + { + m_test.BeginMesh(brush->localToWorld()); + + for(Brush::const_iterator i = brush->getBrush().begin(); i != brush->getBrush().end(); ++i) + { + Face_getClosest(*(*i), m_test, m_bestIntersection, m_texturable); + } + } + else + { + SelectionTestable* selectionTestable = Instance_getSelectionTestable(instance); + if(selectionTestable) + { + bool occluded; + OccludeSelector selector(m_bestIntersection, occluded); + selectionTestable->testSelect(selector, m_test); + if(occluded) + { + Patch* patch = Node_getPatch(path.top()); + if(patch != 0) + { + m_texturable.setTexture = makeCallback3(PatchSetTexture(), *patch); + m_texturable.getTexture = makeCallback3(PatchGetTexture(), *patch); + } + else + { + m_texturable = Texturable(); + } + } + } + } + } + return true; + } +}; + +Texturable Scene_getClosestTexturable(scene::Graph& graph, SelectionTest& test) +{ + Texturable texturable; + graph.traverse(BrushGetClosestFaceVisibleWalker(test, texturable)); + return texturable; +} + +bool Scene_getClosestTexture(scene::Graph& graph, SelectionTest& test, CopiedString& shader, TextureProjection& projection, ContentsFlagsValue& flags) +{ + Texturable texturable = Scene_getClosestTexturable(graph, test); + if(texturable.getTexture != GetTextureCallback()) + { + texturable.getTexture(shader, projection, flags); + return true; + } + return false; +} + +void Scene_setClosestTexture(scene::Graph& graph, SelectionTest& test, const char* shader, const TextureProjection& projection, const ContentsFlagsValue& flags) +{ + Texturable texturable = Scene_getClosestTexturable(graph, test); + if(texturable.setTexture != SetTextureCallback()) + { + texturable.setTexture(shader, projection, flags); + } +} + + +class FaceTexture +{ +public: + TextureProjection m_projection; + ContentsFlagsValue m_flags; +}; + +FaceTexture g_faceTextureClipboard; + +void FaceTextureClipboard_setDefault() +{ + g_faceTextureClipboard.m_flags = ContentsFlagsValue(0, 0, 0, false); + TexDef_Construct_Default(g_faceTextureClipboard.m_projection); +} + +void TextureClipboard_textureSelected(const char* shader) +{ + FaceTextureClipboard_setDefault(); +} + +class TextureBrowser; +extern TextureBrowser g_TextureBrowser; +void TextureBrowser_SetSelectedShader(TextureBrowser& textureBrowser, const char* shader); +const char* TextureBrowser_GetSelectedShader(TextureBrowser& textureBrowser); + +void Scene_copyClosestTexture(SelectionTest& test) +{ + CopiedString shader; + if(Scene_getClosestTexture(GlobalSceneGraph(), test, shader, g_faceTextureClipboard.m_projection, g_faceTextureClipboard.m_flags)) + { + TextureBrowser_SetSelectedShader(g_TextureBrowser, shader.c_str()); + } +} + +void Scene_applyClosestTexture(SelectionTest& test) +{ + UndoableCommand command("facePaintTexture"); + + Scene_setClosestTexture(GlobalSceneGraph(), test, TextureBrowser_GetSelectedShader(g_TextureBrowser), g_faceTextureClipboard.m_projection, g_faceTextureClipboard.m_flags); + + SceneChangeNotify(); +} + + + + + +void SelectedFaces_copyTexture() +{ + if(!g_SelectedFaceInstances.empty()) + { + Face& face = g_SelectedFaceInstances.last().getFace(); + face.GetTexdef(g_faceTextureClipboard.m_projection); + g_faceTextureClipboard.m_flags = face.getShader().m_flags; + + TextureBrowser_SetSelectedShader(g_TextureBrowser, face.getShader().getShader()); + } +} + +void FaceInstance_pasteTexture(FaceInstance& faceInstance) +{ + faceInstance.getFace().SetTexdef(g_faceTextureClipboard.m_projection); + faceInstance.getFace().SetShader(TextureBrowser_GetSelectedShader(g_TextureBrowser)); + faceInstance.getFace().SetFlags(g_faceTextureClipboard.m_flags); + SceneChangeNotify(); +} + +bool SelectedFaces_empty() +{ + return g_SelectedFaceInstances.empty(); +} + +void SelectedFaces_pasteTexture() +{ + UndoableCommand command("facePasteTexture"); + g_SelectedFaceInstances.foreach(FaceInstance_pasteTexture); +} + + + void SurfaceInspector_constructPreferences(PreferencesPage& page) { page.appendCheckBox("", "Surface Inspector Increments Match Grid", g_si_globals.m_bSnapTToGrid); @@ -1328,6 +1569,9 @@ void SurfaceInspector_registerCommands() { GlobalCommands_insert("FitTexture", FreeCaller(), Accelerator('B', (GdkModifierType)GDK_SHIFT_MASK)); GlobalCommands_insert("SurfaceInspector", FreeCaller(), Accelerator('S')); + + GlobalCommands_insert("FaceCopyTexture", FreeCaller()); + GlobalCommands_insert("FacePasteTexture", FreeCaller()); } @@ -1340,6 +1584,8 @@ void SurfaceInspector_Construct() SurfaceInspector_registerCommands(); + FaceTextureClipboard_setDefault(); + GlobalPreferenceSystem().registerPreference("SurfaceWnd", getSurfaceInspector().m_importPosition, getSurfaceInspector().m_exportPosition); GlobalPreferenceSystem().registerPreference("SI_SurfaceTexdef_Scale1", FloatImportStringCaller(g_si_globals.scale[0]), FloatExportStringCaller(g_si_globals.scale[0])); GlobalPreferenceSystem().registerPreference("SI_SurfaceTexdef_Scale2", FloatImportStringCaller(g_si_globals.scale[1]), FloatExportStringCaller(g_si_globals.scale[1])); @@ -1359,6 +1605,8 @@ void SurfaceInspector_Destroy() delete g_SurfaceInspector; } + + #if TEXTOOL_ENABLED namespace TexTool { // namespace hides these symbols from other object-files diff --git a/radiant/surfacedialog.h b/radiant/surfacedialog.h index 3f78b486..034cf1d6 100644 --- a/radiant/surfacedialog.h +++ b/radiant/surfacedialog.h @@ -31,6 +31,11 @@ typedef struct _GtkWindow GtkWindow; void SurfaceInspector_constructWindow(GtkWindow* widget); void SurfaceInspector_destroyWindow(); +bool SelectedFaces_empty(); +void SelectedFaces_copyTexture(); +void SelectedFaces_pasteTexture(); +void FaceTextureClipboard_setDefault(); + // the increment we are using for the surface inspector (this is saved in the prefs) struct si_globals_t