X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=radiant%2Fsurfacedialog.cpp;h=0343bbd2a9a388743cbf2011ff551b8b62a8ba32;hp=b938dd03135070c60196d1b373eb88b2a3446034;hb=3e076b28de8a4117f3d600da203807ec2cefb496;hpb=12b372f89ce109a4db9d510884fbe7d05af79870 diff --git a/radiant/surfacedialog.cpp b/radiant/surfacedialog.cpp index b938dd03..0343bbd2 100644 --- a/radiant/surfacedialog.cpp +++ b/radiant/surfacedialog.cpp @@ -45,7 +45,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include //Shamus: For Textool -#include "generic/callback.h" +#include "signal/isignal.h" #include "generic/object.h" #include "math/vector.h" #include "texturelib.h" @@ -1063,6 +1063,9 @@ GtkWindow* SurfaceInspector::BuildDialog() g_object_set_data(G_OBJECT(check), "handler", gint_to_pointer(handler_id)); } } + + // not allowed to modify detail flag using Surface Inspector + gtk_widget_set_sensitive(GTK_WIDGET(m_contentFlags[BRUSH_DETAIL_FLAG]), FALSE); } } } @@ -1310,6 +1313,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 +1572,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 +1587,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])); @@ -1348,9 +1597,11 @@ void SurfaceInspector_Construct() GlobalPreferenceSystem().registerPreference("SI_SurfaceTexdef_Rotate", FloatImportStringCaller(g_si_globals.rotate), FloatExportStringCaller(g_si_globals.rotate)); GlobalPreferenceSystem().registerPreference("SnapTToGrid", BoolImportStringCaller(g_si_globals.m_bSnapTToGrid), BoolExportStringCaller(g_si_globals.m_bSnapTToGrid)); - GlobalSelectionSystem().addSelectionChangeCallback(FreeCaller1()); - Brush_addTextureChangedCallback(FreeCaller()); - Patch_addTextureChangedCallback(FreeCaller()); + typedef FreeCaller1 SurfaceInspectorSelectionChangedCaller; + GlobalSelectionSystem().addSelectionChangeCallback(SurfaceInspectorSelectionChangedCaller()); + typedef FreeCaller SurfaceInspectorUpdateSelectionCaller; + Brush_addTextureChangedCallback(SurfaceInspectorUpdateSelectionCaller()); + Patch_addTextureChangedCallback(SurfaceInspectorUpdateSelectionCaller()); SurfaceInspector_registerPreferencesPage(); } @@ -1359,6 +1610,8 @@ void SurfaceInspector_Destroy() delete g_SurfaceInspector; } + + #if TEXTOOL_ENABLED namespace TexTool { // namespace hides these symbols from other object-files