]> de.git.xonotic.org Git - xonotic/netradiant.git/commitdiff
added patch support for texture-painting
authorspog <spog>
Sat, 13 May 2006 17:15:08 +0000 (17:15 +0000)
committerspog <spog>
Sat, 13 May 2006 17:15:08 +0000 (17:15 +0000)
git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@68 8a3a26a2-13c4-0310-b231-cf6edde360e5

CHANGES
radiant/brushmanip.cpp
radiant/brushmanip.h
radiant/brushmodule.cpp
radiant/selection.cpp
radiant/surfacedialog.cpp
radiant/surfacedialog.h

diff --git a/CHANGES b/CHANGES
index 0ae8162c1ccf4c54c632ffbb3f7fb753ab0066d6..f25ae8f065bd23680efd3f0428b1ab82bbcbf39f 100644 (file)
--- 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
index 76748797b4ebf54d644d808101ecb51311c2c346..238a58e923119ebb4f70a89b7f54d77b2acb9bba 100644 (file)
@@ -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<SplitSelected>(), Accelerator(GDK_Return, (GdkModifierType)GDK_SHIFT_MASK));
   GlobalCommands_insert("FlipClip", FreeCaller<FlipClipper>(), Accelerator(GDK_Return, (GdkModifierType)GDK_CONTROL_MASK));
 
-  GlobalCommands_insert("FaceCopyTexture", FreeCaller<SelectedFaces_copyTexture>());
-  GlobalCommands_insert("FacePasteTexture", FreeCaller<SelectedFaces_pasteTexture>());
-
   GlobalCommands_insert("MakeDetail", FreeCaller<Select_MakeDetail>(), Accelerator('M', (GdkModifierType)GDK_CONTROL_MASK));
   GlobalCommands_insert("MakeStructural", FreeCaller<Select_MakeStructural>(), Accelerator('S', (GdkModifierType)(GDK_SHIFT_MASK|GDK_CONTROL_MASK)));
 }
index 2c5cb9518ec7de39c90dc61d509e39d71b1b4d10..65d95a11eed396b1206bb4925ad655e673e96a25 100644 (file)
@@ -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();
 
index cbc4c0a28548188ff267f246731085fbc80faa88..66e7a3109062a758e79cf71719d4ad8d942259d9 100644 (file)
@@ -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));
index effdfd3cf296d3e675c32b31995df3391ad7bbc0..ed3e973dbb0b2c4ab7bffe2fa9e77fd7d88aa02c 100644 (file)
@@ -3987,8 +3987,8 @@ public:
   typedef MemberCaller1<Manipulator_, DeviceVector, &Manipulator_::mouseUp> 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);
       }
     }
   }
index 1ec069515956999a373da1c8b079562cade440ba..89785bb7df1c7f04f3321c53a4cce7c16cfdf005 100644 (file)
@@ -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<Face&, CopiedString&, TextureProjection&, ContentsFlagsValue&, void, Face_getTexture> 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<Face&, const char*, const TextureProjection&, const ContentsFlagsValue&, void, Face_setTexture> 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<Patch&, CopiedString&, TextureProjection&, ContentsFlagsValue&, void, Patch_getTexture> PatchGetTexture;
+
+void Patch_setTexture(Patch& patch, const char* shader, const TextureProjection& projection, const ContentsFlagsValue& flags)
+{
+  patch.SetShader(shader);
+}
+typedef Function4<Patch&, const char*, const TextureProjection&, const ContentsFlagsValue&, void, Patch_setTexture> PatchSetTexture;
+
+
+typedef Callback3<CopiedString&, TextureProjection&, ContentsFlagsValue&> GetTextureCallback;
+typedef Callback3<const char*, const TextureProjection&, const ContentsFlagsValue&> 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<SurfaceInspector_FitTexture>(), Accelerator('B', (GdkModifierType)GDK_SHIFT_MASK));
   GlobalCommands_insert("SurfaceInspector", FreeCaller<SurfaceInspector_toggleShown>(), Accelerator('S'));
+
+  GlobalCommands_insert("FaceCopyTexture", FreeCaller<SelectedFaces_copyTexture>());
+  GlobalCommands_insert("FacePasteTexture", FreeCaller<SelectedFaces_pasteTexture>());
 }
 
 
@@ -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
index 3f78b4867bd3c0a2643344b7de3982a74dae5bcb..034cf1d6b90de9a2b51ca343ca1d99a6e2b86890 100644 (file)
@@ -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