├── addons └── Wireframe Tool │ ├── images │ ├── 01.png │ ├── 02.png │ ├── 03.png │ ├── 04.png │ └── icon.png │ ├── plugin.cfg │ ├── materials │ ├── occluderMat.tres │ ├── outlineMat.tres │ ├── litMat.tres │ └── editMat.tres │ ├── helpDialog.tscn │ ├── dock.gd │ ├── dock.tscn │ └── wireframetool.gd ├── README.md └── LICENSE /addons/Wireframe Tool/images/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GlaDOSik/GodotWireframePlugin/HEAD/addons/Wireframe Tool/images/01.png -------------------------------------------------------------------------------- /addons/Wireframe Tool/images/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GlaDOSik/GodotWireframePlugin/HEAD/addons/Wireframe Tool/images/02.png -------------------------------------------------------------------------------- /addons/Wireframe Tool/images/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GlaDOSik/GodotWireframePlugin/HEAD/addons/Wireframe Tool/images/03.png -------------------------------------------------------------------------------- /addons/Wireframe Tool/images/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GlaDOSik/GodotWireframePlugin/HEAD/addons/Wireframe Tool/images/04.png -------------------------------------------------------------------------------- /addons/Wireframe Tool/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GlaDOSik/GodotWireframePlugin/HEAD/addons/Wireframe Tool/images/icon.png -------------------------------------------------------------------------------- /addons/Wireframe Tool/plugin.cfg: -------------------------------------------------------------------------------- 1 | [plugin] 2 | 3 | name="Wireframe Tool" 4 | description="A tool for creating customized wireframe from mesh." 5 | author="Ludek Novotny" 6 | version="2.0" 7 | script="wireframetool.gd" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Godot Wireframe Tool 2 | A plugin for creating customized wireframes for Godot engine. 3 | 4 | ![image01](https://github.com/GlaDOSik/GodotWireframePlugin/blob/master/addons/Wireframe%20Tool/images/01.png) 5 | 6 | ![image02](https://github.com/GlaDOSik/GodotWireframePlugin/blob/master/addons/Wireframe%20Tool/images/02.png) 7 | 8 | ![image03](https://github.com/GlaDOSik/GodotWireframePlugin/blob/master/addons/Wireframe%20Tool/images/03.png) 9 | 10 | ![image04](https://github.com/GlaDOSik/GodotWireframePlugin/blob/master/addons/Wireframe%20Tool/images/04.png) 11 | -------------------------------------------------------------------------------- /addons/Wireframe Tool/materials/occluderMat.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="ShaderMaterial" load_steps=2 format=1] 2 | 3 | [sub_resource type="MaterialShader" id=1] 4 | 5 | _code = { "fragment":"", "fragment_ofs":0, "light":"uniform color ambient;\nLIGHT = ambient.xyz;", "light_ofs":0, "vertex":"VERTEX = VERTEX * 1.005;", "vertex_ofs":0 } 6 | 7 | [resource] 8 | 9 | flags/visible = true 10 | flags/double_sided = false 11 | flags/invert_faces = false 12 | flags/unshaded = false 13 | flags/on_top = false 14 | flags/lightmap_on_uv2 = true 15 | flags/colarray_is_srgb = false 16 | params/blend_mode = 0 17 | params/depth_draw = 1 18 | params/line_width = 1.4013e-43 19 | shader/shader = SubResource( 1 ) 20 | shader_param/ambient = Color( 0.117647, 0.12549, 0.14902, 1 ) 21 | 22 | -------------------------------------------------------------------------------- /addons/Wireframe Tool/materials/outlineMat.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="ShaderMaterial" load_steps=2 format=1] 2 | 3 | [sub_resource type="MaterialShader" id=1] 4 | 5 | _code = { "fragment":"float ndot = dot(NORMAL, VERTEX);\nif (ndot <= 0.0){\nDIFFUSE_ALPHA = vec4(0,0,0,0);\n}\nelse{\nDIFFUSE_ALPHA = vec4(COLOR.xyz, 1.0);\n}", "fragment_ofs":0, "light":"LIGHT = DIFFUSE;", "light_ofs":0, "vertex":"", "vertex_ofs":0 } 6 | 7 | [resource] 8 | 9 | flags/visible = true 10 | flags/double_sided = false 11 | flags/invert_faces = false 12 | flags/unshaded = false 13 | flags/on_top = false 14 | flags/lightmap_on_uv2 = true 15 | flags/colarray_is_srgb = false 16 | params/blend_mode = 0 17 | params/depth_draw = 1 18 | params/line_width = 2.0 19 | shader/shader = SubResource( 1 ) 20 | 21 | -------------------------------------------------------------------------------- /addons/Wireframe Tool/materials/litMat.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="ShaderMaterial" load_steps=2 format=1] 2 | 3 | [sub_resource type="MaterialShader" id=1] 4 | 5 | _code = { "fragment":"DIFFUSE = COLOR.xyz;", "fragment_ofs":0, "light":"uniform color ambient;\nfloat ndot = dot(NORMAL, LIGHT_DIR)*0.5+0.5;\n\nLIGHT = ((1.0 - ndot) * ambient.xyz) + (ndot * DIFFUSE * LIGHT_DIFFUSE);", "light_ofs":0, "vertex":"", "vertex_ofs":0 } 6 | 7 | [resource] 8 | 9 | flags/visible = true 10 | flags/double_sided = false 11 | flags/invert_faces = false 12 | flags/unshaded = false 13 | flags/on_top = false 14 | flags/lightmap_on_uv2 = true 15 | flags/colarray_is_srgb = false 16 | params/blend_mode = 0 17 | params/depth_draw = 1 18 | params/line_width = 1.35926e-43 19 | shader/shader = SubResource( 1 ) 20 | shader_param/ambient = Color( 0.117647, 0.12549, 0.14902, 1 ) 21 | 22 | -------------------------------------------------------------------------------- /addons/Wireframe Tool/materials/editMat.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="ShaderMaterial" load_steps=2 format=1] 2 | 3 | [sub_resource type="MaterialShaderGraph" id=1] 4 | 5 | _code = { "fragment":"vec3 nd1sl9=COLOR.rgb;\nvec3 DIFFUSE_OUT=vec3(0,0,0);\nfloat ALPHA_OUT=0;\nDIFFUSE_OUT=nd1sl9;\nDIFFUSE=DIFFUSE_OUT;\n", "fragment_ofs":0, "light":"vec3 nd1sl5=DIFFUSE;\nLIGHT=nd1sl5;\n", "light_ofs":0, "vertex":"", "vertex_ofs":0 } 6 | _data = { "shaders":[ [ 0, 33, Vector2( 350, 40 ), null, null, [ ], 1, 0, Vector2( 50, 40 ), null, null, [ ] ], [ 0, 33, Vector2( 481, 50 ), null, null, [ 0, 1, 9 ], 1, 0, Vector2( 50, 40 ), null, null, [ ] ], [ 0, 33, Vector2( 524, 29 ), null, null, [ 0, 1, 5 ], 1, 0, Vector2( 50, 40 ), null, null, [ ] ] ] } 7 | 8 | [resource] 9 | 10 | flags/visible = true 11 | flags/double_sided = false 12 | flags/invert_faces = false 13 | flags/unshaded = true 14 | flags/on_top = false 15 | flags/lightmap_on_uv2 = true 16 | flags/colarray_is_srgb = false 17 | params/blend_mode = 0 18 | params/depth_draw = 1 19 | params/line_width = 1.0 20 | shader/shader = SubResource( 1 ) 21 | 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /addons/Wireframe Tool/helpDialog.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene format=1] 2 | 3 | [node name="WindowDialog" type="WindowDialog"] 4 | 5 | focus/ignore_mouse = false 6 | focus/stop_mouse = true 7 | size_flags/horizontal = 2 8 | size_flags/vertical = 2 9 | margin/left = 0.0 10 | margin/top = 0.0 11 | margin/right = 561.0 12 | margin/bottom = 361.0 13 | popup/exclusive = false 14 | window/title = "Wireframe Tool v2.0 - by Ludek Novotny" 15 | __meta__ = { "_edit_lock_":true } 16 | 17 | [node name="RichTextLabel" type="RichTextLabel" parent="."] 18 | 19 | focus/ignore_mouse = false 20 | focus/stop_mouse = true 21 | size_flags/horizontal = 2 22 | size_flags/vertical = 2 23 | margin/left = 0.0 24 | margin/top = 0.0 25 | margin/right = 554.0 26 | margin/bottom = 356.0 27 | bbcode/enabled = true 28 | bbcode/bbcode = "Do you like thin sharp lines of [color=gray]Kentucky Route Zero[/color]\? Do you like [color=lime]Battlezone[/color]\? Do you want to use wireframe art style\? Do you need outline shader\? The problem of pure wireframe look is that every edge of the model is rendered. And because every model has to be triangulated before rendering, you will get a very noisy look with a lot of unwanted triangles. This tool will help you to create customized wireframe from imported mesh.\n\n[color=#f43799][u]HOW TO USE:[/u][/color]\n\n[color=#9393ce]Target Mesh/Surface:[/color] Select the surface you want to edit. You can select multiple MeshInstances in editor and switch between them. Don\'t select multiple meshes if you want to edit the wireframe. Use it only for Copy tool. \n[color=#9393ce]Rename Surface:[/color] You can rename surfaces in Inspector but if you generated the wireframe, this mesh now has metadata and they are link to the wireframe by surface name. So if you generated the wireframe, rename the surface using this tool! The name should be unique.\n[color=#9393ce]Delete Surface:[/color] This will delete selected surface together with metadata. No undo.\n[color=#9393ce]Source Mesh/Surface:[/color] Select the surface you want to copy. You can\'t unfortunately copy wireframe surface (this is an engine problem - MeshDataTool can\'t work with primitive GL_LINES).\n[color=#9393ce]Copy:[/color] Copy selected source surface to selected target mesh. If you want to bundle occlusion geometry together with wireframe to one mesh, copy occlusion geometry to wireframe. It won\'t work the other way (wireframe to occlusion). You can\'t copy surface if there\'s surface in target mesh with the same name.\n\n[color=#f43799]Wireframe Tools[/color]\n[color=#9393ce]Generate:[/color] Generate wireframe from selected surface (target surface). Metadata are generated and saved to Mesh.\n[color=#9393ce]Commit:[/color] If you\'re happy with the wireframe and you don\'t want to edit it anymore, you can commit the changes. After this step, you won\'t be able to edit the wireframe but your scene file will be smaller because of deleted metadata. There is no point to export the game with unnecessary metadata.\n[color=#9393ce]Cancel:[/color] This will revert the surface back to it\'s orginal state before the wireframe was generated. Metadata will be of course deleted too.\n\n[color=#f43799]Selection Tools[/color]\n[color=#9393ce]None:[/color] No selection tool. Plugin won\'t capture your mouse input so you will be able to use gizmos of 3D editor.\n[color=#9393ce]Vertex:[/color] Select one vertex. Any other selection tool + Alt will also do vertex selection. If you click on selected vertex, it will be deselected. Ctrl + vertex selection works as a color picker.\n[color=#9393ce]Edge:[/color] Select one or more edges. If you click on selected edge, it will be deselected.\n[color=#9393ce]All:[/color] Select every edge in surface. If every edge is already selected, they will be deselected. It works like in Blender. Shortcut is key A.\n[color=#9393ce]Inverse:[/color] Inverse the selection. Shortcut is key I.\n\n[color=#f43799]Actions[/color]\n[color=#9393ce]Delete:[/color] Delete selected vertex or edges. Shortcut is key D.\n[color=#9393ce]Color:[/color] Color selected vertex or edges with color next to this button. Shortcut is key C.\n\n[color=#f43799]Materials[/color]\n[color=#9393ce]Unlit:[/color] Assign to surface a simple unlit material which shows vertex colors.\n[color=#9393ce]Lit:[/color] Assign to surface a simple lit material which shows vertex colors. Formula is based on Half Lambert. Don\'t forget to select Ambient color - color of dark areas.\n[color=#9393ce]Outline:[/color] You can create an outline using this material. Create a separate wireframe for outline (from FLAT shaded mesh !!!) and use this shader on it. Occlude unwanted wires by occlusion geometry.\n[color=#9393ce]Occlusion:[/color] This material is for occlusion geometry. By default, wireframe is not opaque. You have to create an occlusion mesh and assign this material to it. Don\'t forget to select Ambient color. It should be same as the background color so this mesh will look like invisible.\n\n[color=#f43799][u]CONTROLS:[/u][/color]\nLMB: Selection tool\nLMB + Alt: Vertex selection tool\nVertex selection tool + Ctrl: Color picker\nD: Delete selected edge(s) or vertex\nA: Select/deselect all\nI: Inverse selection\nC: Color selection\nCtrl + Z: Editor undo\nShift + Ctrl + Z: Editor redo\n\n[color=#f43799][u]FAQ:[/u][/color]\n[color=lime]I can\'t select edge/vertex[/color] \nYour model probably has some duplicated edges. This happens when your model is flat shaded. The edge is selected but you can\'t see it because there is another one on the top of it. Either delete one of them or smooth your model before export.\n\n[color=lime]I selected the valid surface but I can\'t edit the wireframe[/color] \nDid you rename the surface using Inspector\? You can do it until you hit Generate button. Use Rename tool after that.\n\n[color=lime]I selected multiple MeshInstances but I can\'t edit wireframe[/color]\nMultiple selection works right now only with Copy tool. If you want to edit wireframe, select only one MeshInstance.\n\n[color=lime]Commit/Cancel deleted my colors[/color]\nNo, they didn\'t. Surface which is being edited has a special unshaded material which shows vertex colors. Commit/Cancel buttons will delete this material, but your model still has vertex colors.\n\n[color=lime]I would like to change thickness of lines. How\?[/color]\nChange Line Width property in material.\n\n[color=#f43799][u]Changelog 1.0 -> 2.0:[/u][/color]\n- functions of plugin are now inside the new dock\n- metadata are now saved to Mesh instead of MeshInstance. This breaks the compatibility but makes more sense.\n- support of multiple surfaces per Mesh\n- undo/redo support for wft actions\n- copy tool (copy selected surface from one Mesh to another)\n- renaming tool (every change of surface name needs to be reflected in metadata)\n- new selection tool None won\'t capture input so you can use spatial editor gizmos\n- new selection tools Loop, All and Inverse\n- selection tool Vertex works also as a color picker (LMB + Ctrl)\n- actions Color (selected vertex/edges) and Delete (selected vertex/edges)\n- new outline shader\n- UVs and bones are now transfered to wireframe mesh\n- warnings now show inside the dock" 29 | visible_characters = -1 30 | __meta__ = { "_edit_lock_":true } 31 | 32 | 33 | -------------------------------------------------------------------------------- /addons/Wireframe Tool/dock.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends ScrollContainer 3 | 4 | const SELECTION_TOOL_NONE = 0 5 | const SELECTION_TOOL_VERTEX = 1 6 | const SELECTION_TOOL_EDGES = 2 7 | const SELECTION_TOOL_LOOP = 3 8 | const SELECTION_TOOL_ALL = 4 9 | const SELECTION_TOOL_INVERSE = 5 10 | 11 | var wftScript #reference to wireframetool.gd 12 | var buttons = [] 13 | var isDockDisabled = false 14 | var isWFTDisabled = true 15 | 16 | func _enter_tree(): 17 | get_node("vbox/btnHelp").connect("pressed", wftScript, "showHelp") 18 | buttons.append(get_node("vbox/hboxSur1/btnTMesh")) 19 | buttons[0].set_text("Mesh")#this doesn't work in editor 20 | buttons[0].connect("item_selected", wftScript, "targetMeshSelection") 21 | buttons.append(get_node("vbox/hboxSur1/btnTSur")) 22 | buttons[1].set_text("Surface") 23 | buttons[1].connect("item_selected", wftScript, "targetSurfaceSelection") 24 | 25 | buttons.append(get_node("vbox/hboxSur2/btnRenameS")) 26 | buttons[2].connect("pressed", wftScript, "renameSurface") 27 | #buttons.append(get_node("vbox/hboxSur2/txtedSurName")) 28 | buttons.append(get_node("vbox/hboxSur2/btnRenameOk")) 29 | buttons[3].connect("pressed", wftScript, "renameSurfaceOK") 30 | buttons.append(get_node("vbox/hboxSur2/btnDeleteS")) 31 | buttons[4].connect("pressed", wftScript, "deleteSurface") 32 | 33 | buttons.append(get_node("vbox/hboxSur3/btnSMesh")) 34 | buttons[5].set_text("Mesh") 35 | buttons[5].connect("item_selected", wftScript, "sourceMeshSelection") 36 | buttons.append(get_node("vbox/hboxSur3/btnSSur")) 37 | buttons[6].set_text("Surface") 38 | buttons.append(get_node("vbox/hboxSur3/btnCopyS")) 39 | buttons[7].connect("pressed", wftScript, "copySurface") 40 | 41 | buttons.append(get_node("vbox/hboxWFT/btnGenerate")) 42 | buttons[8].connect("pressed", wftScript, "generateWirefame") 43 | buttons.append(get_node("vbox/hboxWFT/btnCommit")) 44 | buttons[9].connect("pressed", wftScript, "commitWireframe") 45 | buttons.append(get_node("vbox/hboxWFT/btnCancel")) 46 | buttons[10].connect("pressed", wftScript, "cancelWireframe") 47 | 48 | buttons.append(get_node("vbox/group/GridContainer/btnNone")) 49 | buttons[11].connect("pressed", self, "setToolNone") 50 | buttons.append(get_node("vbox/group/GridContainer/btnVertex")) 51 | buttons[12].connect("pressed", self, "setToolVertex") 52 | buttons.append(get_node("vbox/group/GridContainer/btnEdge")) 53 | buttons[13].connect("pressed", self, "setToolEdge") 54 | buttons.append(get_node("vbox/group/GridContainer/btnLoop")) 55 | buttons[14].connect("pressed", self, "setToolLoop") 56 | buttons.append(get_node("vbox/group/GridContainer/btnAll")) 57 | buttons[15].connect("pressed", self, "setToolALL") 58 | buttons.append(get_node("vbox/group/GridContainer/btnInverse")) 59 | buttons[16].connect("pressed", self, "setToolInverse") 60 | 61 | buttons.append(get_node("vbox/gridActions/btnDelete")) 62 | buttons[17].connect("pressed", wftScript, "deleteSelection") 63 | buttons.append(get_node("vbox/gridActions/btnColor")) 64 | buttons[18].connect("pressed", wftScript, "colorSelection") 65 | buttons.append(get_node("vbox/gridActions/ColorPickerButton")) 66 | 67 | buttons.append(get_node("vbox/hboxMaterials/btnUnlit")) 68 | buttons[20].connect("pressed", wftScript, "setUnlitShader") 69 | buttons.append(get_node("vbox/hboxMaterials/btnLit")) 70 | buttons[21].connect("pressed", wftScript, "setLitShader") 71 | buttons.append(get_node("vbox/hboxMaterials/btnOutline")) 72 | buttons[22].connect("pressed", wftScript, "setOutlineShader") 73 | get_node("vbox/hboxMaterials/btnOccluder").connect("pressed", wftScript, "setOccluderShader") 74 | disableAll(true) 75 | 76 | func _exit_tree(): 77 | get_node("vbox/btnHelp").disconnect("pressed", wftScript, "showHelp") 78 | buttons[0].disconnect("item_selected", wftScript, "targetMeshSelection") 79 | buttons[1].disconnect("item_selected", wftScript, "targetSurfaceSelection") 80 | buttons[2].disconnect("pressed", wftScript, "renameSurface") 81 | buttons[3].disconnect("pressed", wftScript, "renameSurfaceOK") 82 | buttons[4].disconnect("pressed", wftScript, "deleteSurface") 83 | buttons[5].disconnect("item_selected", wftScript, "sourceMeshSelection") 84 | buttons[7].disconnect("pressed", wftScript, "copySurface") 85 | buttons[8].disconnect("pressed", wftScript, "generateWirefame") 86 | buttons[9].disconnect("pressed", wftScript, "commitWireframe") 87 | buttons[10].disconnect("pressed", wftScript, "cancelWireframe") 88 | buttons[11].disconnect("pressed", self, "setToolNone") 89 | buttons[12].disconnect("pressed", self, "setToolVertex") 90 | buttons[13].disconnect("pressed", self, "setToolEdge") 91 | buttons[14].disconnect("pressed", self, "setToolLoop") 92 | buttons[15].disconnect("pressed", self, "setToolALL") 93 | buttons[16].disconnect("pressed", self, "setToolInverse") 94 | buttons[17].disconnect("pressed", wftScript, "deleteSelection") 95 | buttons[18].disconnect("pressed", wftScript, "colorSelection") 96 | buttons[20].disconnect("pressed", wftScript, "setUnlitShader") 97 | buttons[21].disconnect("pressed", wftScript, "setLitShader") 98 | buttons[22].disconnect("pressed", wftScript, "setOutlineShader") 99 | get_node("vbox/hboxMaterials/btnOccluder").disconnect("pressed", wftScript, "setOccluderShader") 100 | 101 | func setToolNone(): 102 | wftScript.activeTool = SELECTION_TOOL_NONE 103 | func setToolVertex(): 104 | wftScript.activeTool = SELECTION_TOOL_VERTEX 105 | func setToolEdge(): 106 | wftScript.activeTool = SELECTION_TOOL_EDGES 107 | func setToolLoop(): 108 | wftScript.activeTool = SELECTION_TOOL_LOOP 109 | func setToolALL(): 110 | wftScript.activeTool = SELECTION_TOOL_ALL 111 | func setToolInverse(): 112 | wftScript.activeTool = SELECTION_TOOL_INVERSE 113 | 114 | func setTargetMeshName(name, uid): 115 | buttons[0].add_item(name, uid) 116 | 117 | func setTargetSurfaceName(name): 118 | buttons[1].add_item(name) 119 | 120 | func setSourceMeshName(name, uid): 121 | buttons[5].add_item(name, uid) 122 | 123 | func setSourceSurfaceName(name): 124 | buttons[6].add_item(name) 125 | 126 | ######################################################################### 127 | 128 | func getSelTargetMeshId(): 129 | return buttons[0].get_selected_ID() 130 | 131 | func getSelTargetSurfaceName(): 132 | return buttons[1].get_item_text(buttons[1].get_selected()) 133 | 134 | func getSelSourceMeshId(): 135 | return buttons[5].get_selected_ID() 136 | 137 | func getSelSourceSurfaceName(): 138 | return buttons[6].get_item_text(buttons[6].get_selected()) 139 | 140 | ######################################################################### 141 | 142 | func clearSelTargetMesh(): 143 | buttons[0].clear() 144 | 145 | func clearSelTargetSurface(): 146 | buttons[1].clear() 147 | 148 | func clearSelSourceMesh(): 149 | buttons[5].clear() 150 | 151 | func clearSelSourceSurface(): 152 | buttons[6].clear() 153 | 154 | ########################################### 155 | func getColor(): 156 | return get_node("vbox/gridActions/ColorPickerButton").get_color() 157 | 158 | func setColor(color): 159 | get_node("vbox/gridActions/ColorPickerButton").set_color(color) 160 | 161 | func setWarning(text): 162 | get_node("vbox/lblWarning").set_text(text) 163 | 164 | func getWarning(): 165 | return get_node("vbox/lblWarning").get_text() 166 | 167 | func getRenameSurfaceText(): 168 | return get_node("vbox/hboxSur2/txtedSurName").get_text() 169 | 170 | func showRenameSurface(show): 171 | buttons[2].set_hidden(show) 172 | get_node("vbox/hboxSur2/txtedSurName").set_hidden(!show) 173 | buttons[3].set_hidden(!show) 174 | if (show): 175 | get_node("vbox/hboxSur2/txtedSurName").set_text(getSelTargetSurfaceName()) 176 | 177 | func disableTarget(disable): 178 | buttons[0].set_disabled(disable) 179 | buttons[1].set_disabled(disable) 180 | buttons[2].set_disabled(disable) 181 | buttons[3].set_disabled(disable) 182 | buttons[4].set_disabled(disable) 183 | 184 | func disableSurfaceCopy(disable): 185 | buttons[5].set_disabled(disable) 186 | buttons[6].set_disabled(disable) 187 | buttons[7].set_disabled(disable) 188 | 189 | func disableWFT(disable): 190 | isWFTDisabled = disable 191 | buttons[8].set_disabled(!disable) 192 | buttons[9].set_disabled(disable) 193 | buttons[10].set_disabled(disable) 194 | buttons[11].set_disabled(disable) 195 | buttons[12].set_disabled(disable) 196 | buttons[13].set_disabled(disable) 197 | buttons[14].set_disabled(disable) 198 | buttons[15].set_disabled(disable) 199 | buttons[16].set_disabled(disable) 200 | buttons[17].set_disabled(disable) 201 | buttons[18].set_disabled(disable) 202 | buttons[19].set_disabled(disable) 203 | buttons[20].set_disabled(disable) 204 | buttons[21].set_disabled(disable) 205 | buttons[22].set_disabled(disable) 206 | buttons[22].set_disabled(disable) 207 | 208 | func disableAll(disable): 209 | for button in buttons: 210 | if (!button.is_disabled()): 211 | button.set_disabled(disable) 212 | 213 | func cleanAndLock(): 214 | buttons[0].clear() 215 | buttons[1].clear() 216 | buttons[5].clear() 217 | buttons[6].clear() 218 | disableAll(true) -------------------------------------------------------------------------------- /addons/Wireframe Tool/dock.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=1] 2 | 3 | [ext_resource path="res://addons/Wireframe Tool/dock.gd" type="Script" id=1] 4 | 5 | [node name="WFT" type="ScrollContainer"] 6 | 7 | rect/min_size = Vector2( 0, 200 ) 8 | focus/ignore_mouse = false 9 | focus/stop_mouse = true 10 | size_flags/horizontal = 2 11 | size_flags/vertical = 3 12 | margin/left = 0.0 13 | margin/top = 0.0 14 | margin/right = 213.0 15 | margin/bottom = 376.0 16 | scroll/horizontal = true 17 | scroll/vertical = true 18 | script/script = ExtResource( 1 ) 19 | 20 | [node name="vbox" type="VBoxContainer" parent="."] 21 | 22 | rect/min_size = Vector2( 0, 410 ) 23 | focus/ignore_mouse = false 24 | focus/stop_mouse = false 25 | size_flags/horizontal = 2 26 | size_flags/vertical = 3 27 | margin/left = 0.0 28 | margin/top = 0.0 29 | margin/right = 201.0 30 | margin/bottom = 418.0 31 | alignment = 0 32 | 33 | [node name="lblChooseSur" type="Label" parent="vbox"] 34 | 35 | focus/ignore_mouse = true 36 | focus/stop_mouse = true 37 | size_flags/horizontal = 2 38 | size_flags/vertical = 0 39 | margin/left = 0.0 40 | margin/top = 0.0 41 | margin/right = 201.0 42 | margin/bottom = 14.0 43 | text = "Target Mesh/Surface" 44 | percent_visible = 1.0 45 | lines_skipped = 0 46 | max_lines_visible = -1 47 | 48 | [node name="hboxSur1" type="HBoxContainer" parent="vbox"] 49 | 50 | focus/ignore_mouse = false 51 | focus/stop_mouse = false 52 | size_flags/horizontal = 2 53 | size_flags/vertical = 2 54 | margin/left = 0.0 55 | margin/top = 18.0 56 | margin/right = 201.0 57 | margin/bottom = 38.0 58 | alignment = 0 59 | 60 | [node name="btnTMesh" type="OptionButton" parent="vbox/hboxSur1"] 61 | 62 | rect/min_size = Vector2( 95, 0 ) 63 | hint/tooltip = "You can select multiple meshes. Choose one you want to use. This will be the target mesh if you going to copy surface from another mesh." 64 | focus/ignore_mouse = false 65 | focus/stop_mouse = true 66 | size_flags/horizontal = 2 67 | size_flags/vertical = 2 68 | margin/left = 0.0 69 | margin/top = 0.0 70 | margin/right = 95.0 71 | margin/bottom = 20.0 72 | disabled = true 73 | toggle_mode = false 74 | enabled_focus_mode = 2 75 | shortcut = null 76 | text = "Mesh" 77 | flat = false 78 | align = 0 79 | selected = -1 80 | items = [ ] 81 | 82 | [node name="btnTSur" type="OptionButton" parent="vbox/hboxSur1"] 83 | 84 | rect/min_size = Vector2( 95, 0 ) 85 | hint/tooltip = "You can edit only one surface at time. Select the desired one. This surface will be edited through selection tools, actions and shaders." 86 | focus/ignore_mouse = false 87 | focus/stop_mouse = true 88 | size_flags/horizontal = 2 89 | size_flags/vertical = 2 90 | margin/left = 99.0 91 | margin/top = 0.0 92 | margin/right = 194.0 93 | margin/bottom = 20.0 94 | disabled = true 95 | toggle_mode = false 96 | enabled_focus_mode = 2 97 | shortcut = null 98 | text = "Surface" 99 | flat = false 100 | align = 0 101 | selected = -1 102 | items = [ ] 103 | 104 | [node name="hboxSur2" type="HBoxContainer" parent="vbox"] 105 | 106 | focus/ignore_mouse = false 107 | focus/stop_mouse = false 108 | size_flags/horizontal = 2 109 | size_flags/vertical = 2 110 | margin/left = 0.0 111 | margin/top = 42.0 112 | margin/right = 201.0 113 | margin/bottom = 62.0 114 | alignment = 0 115 | 116 | [node name="btnRenameS" type="Button" parent="vbox/hboxSur2"] 117 | 118 | hint/tooltip = "Do NOT rename surfaces through the editor, if you used wireframe tool (Generate) on the mesh." 119 | focus/ignore_mouse = false 120 | focus/stop_mouse = true 121 | size_flags/horizontal = 2 122 | size_flags/vertical = 2 123 | margin/left = 0.0 124 | margin/top = 0.0 125 | margin/right = 96.0 126 | margin/bottom = 20.0 127 | disabled = true 128 | toggle_mode = false 129 | enabled_focus_mode = 2 130 | shortcut = null 131 | text = "Rename surf." 132 | flat = false 133 | 134 | [node name="txtedSurName" type="LineEdit" parent="vbox/hboxSur2"] 135 | 136 | visibility/visible = false 137 | rect/min_size = Vector2( 85, 0 ) 138 | hint/tooltip = "Rename the surface. If your name isn\'t unique, the tool will make sure it is." 139 | focus/ignore_mouse = false 140 | focus/stop_mouse = true 141 | size_flags/horizontal = 2 142 | size_flags/vertical = 2 143 | margin/left = 0.0 144 | margin/top = 0.0 145 | margin/right = 85.0 146 | margin/bottom = 20.0 147 | placeholder/alpha = 0.6 148 | focus_mode = 2 149 | caret/caret_blink = false 150 | caret/caret_blink_speed = 0.65 151 | 152 | [node name="btnRenameOk" type="Button" parent="vbox/hboxSur2"] 153 | 154 | visibility/visible = false 155 | focus/ignore_mouse = false 156 | focus/stop_mouse = true 157 | size_flags/horizontal = 2 158 | size_flags/vertical = 2 159 | margin/left = 0.0 160 | margin/top = 0.0 161 | margin/right = 31.0 162 | margin/bottom = 20.0 163 | disabled = true 164 | toggle_mode = false 165 | enabled_focus_mode = 2 166 | shortcut = null 167 | text = "OK" 168 | flat = false 169 | 170 | [node name="btnDeleteS" type="Button" parent="vbox/hboxSur2"] 171 | 172 | hint/tooltip = "Delete selected surface." 173 | focus/ignore_mouse = false 174 | focus/stop_mouse = true 175 | size_flags/horizontal = 2 176 | size_flags/vertical = 2 177 | margin/left = 100.0 178 | margin/top = 0.0 179 | margin/right = 187.0 180 | margin/bottom = 20.0 181 | disabled = true 182 | toggle_mode = false 183 | enabled_focus_mode = 2 184 | shortcut = null 185 | text = "Delete surf." 186 | flat = false 187 | 188 | [node name="lblCopySur" type="Label" parent="vbox"] 189 | 190 | focus/ignore_mouse = true 191 | focus/stop_mouse = true 192 | size_flags/horizontal = 2 193 | size_flags/vertical = 0 194 | margin/left = 0.0 195 | margin/top = 66.0 196 | margin/right = 201.0 197 | margin/bottom = 80.0 198 | text = "Source Mesh/Surface" 199 | percent_visible = 1.0 200 | lines_skipped = 0 201 | max_lines_visible = -1 202 | 203 | [node name="hboxSur3" type="HBoxContainer" parent="vbox"] 204 | 205 | focus/ignore_mouse = false 206 | focus/stop_mouse = false 207 | size_flags/horizontal = 2 208 | size_flags/vertical = 2 209 | margin/left = 0.0 210 | margin/top = 84.0 211 | margin/right = 201.0 212 | margin/bottom = 104.0 213 | alignment = 0 214 | 215 | [node name="btnSMesh" type="OptionButton" parent="vbox/hboxSur3"] 216 | 217 | rect/min_size = Vector2( 75, 0 ) 218 | hint/tooltip = "Select source mesh." 219 | focus/ignore_mouse = false 220 | focus/stop_mouse = true 221 | size_flags/horizontal = 2 222 | size_flags/vertical = 2 223 | margin/left = 0.0 224 | margin/top = 0.0 225 | margin/right = 75.0 226 | margin/bottom = 20.0 227 | disabled = true 228 | toggle_mode = false 229 | enabled_focus_mode = 2 230 | shortcut = null 231 | text = "Mesh" 232 | flat = false 233 | align = 0 234 | selected = -1 235 | items = [ ] 236 | 237 | [node name="btnSSur" type="OptionButton" parent="vbox/hboxSur3"] 238 | 239 | rect/min_size = Vector2( 75, 0 ) 240 | hint/tooltip = "Select source surface from selected mesh." 241 | focus/ignore_mouse = false 242 | focus/stop_mouse = true 243 | size_flags/horizontal = 2 244 | size_flags/vertical = 2 245 | margin/left = 79.0 246 | margin/top = 0.0 247 | margin/right = 154.0 248 | margin/bottom = 20.0 249 | disabled = true 250 | toggle_mode = false 251 | enabled_focus_mode = 2 252 | shortcut = null 253 | text = "Surface" 254 | flat = false 255 | clip_text = true 256 | align = 0 257 | selected = -1 258 | items = [ ] 259 | 260 | [node name="btnCopyS" type="Button" parent="vbox/hboxSur3"] 261 | 262 | hint/tooltip = "Copy this surface to target mesh." 263 | focus/ignore_mouse = false 264 | focus/stop_mouse = true 265 | size_flags/horizontal = 2 266 | size_flags/vertical = 2 267 | margin/left = 158.0 268 | margin/top = 0.0 269 | margin/right = 201.0 270 | margin/bottom = 20.0 271 | disabled = true 272 | toggle_mode = false 273 | enabled_focus_mode = 2 274 | shortcut = null 275 | text = "Copy" 276 | flat = false 277 | 278 | [node name="sep1" type="HSeparator" parent="vbox"] 279 | 280 | focus/ignore_mouse = false 281 | focus/stop_mouse = true 282 | size_flags/horizontal = 2 283 | size_flags/vertical = 2 284 | margin/left = 0.0 285 | margin/top = 108.0 286 | margin/right = 201.0 287 | margin/bottom = 111.0 288 | custom_constants/separation = 0 289 | 290 | [node name="lblWFTools" type="Label" parent="vbox"] 291 | 292 | focus/ignore_mouse = true 293 | focus/stop_mouse = true 294 | size_flags/horizontal = 2 295 | size_flags/vertical = 0 296 | margin/left = 0.0 297 | margin/top = 115.0 298 | margin/right = 201.0 299 | margin/bottom = 129.0 300 | text = "Wireframe Tools" 301 | percent_visible = 1.0 302 | lines_skipped = 0 303 | max_lines_visible = -1 304 | 305 | [node name="hboxWFT" type="HBoxContainer" parent="vbox"] 306 | 307 | focus/ignore_mouse = false 308 | focus/stop_mouse = false 309 | size_flags/horizontal = 2 310 | size_flags/vertical = 2 311 | margin/left = 0.0 312 | margin/top = 133.0 313 | margin/right = 201.0 314 | margin/bottom = 153.0 315 | alignment = 0 316 | 317 | [node name="btnGenerate" type="Button" parent="vbox/hboxWFT"] 318 | 319 | hint/tooltip = "Generate a wireframe from target surface." 320 | focus/ignore_mouse = false 321 | focus/stop_mouse = true 322 | size_flags/horizontal = 2 323 | size_flags/vertical = 2 324 | margin/left = 0.0 325 | margin/top = 0.0 326 | margin/right = 71.0 327 | margin/bottom = 20.0 328 | disabled = true 329 | toggle_mode = true 330 | click_on_press = true 331 | enabled_focus_mode = 2 332 | shortcut = null 333 | text = "Generate" 334 | flat = false 335 | 336 | [node name="btnCommit" type="Button" parent="vbox/hboxWFT"] 337 | 338 | hint/tooltip = "Commit the edits and delete metadata. After this, you won\'t be able to edit the wireframe again." 339 | focus/ignore_mouse = false 340 | focus/stop_mouse = true 341 | size_flags/horizontal = 2 342 | size_flags/vertical = 2 343 | margin/left = 75.0 344 | margin/top = 0.0 345 | margin/right = 138.0 346 | margin/bottom = 20.0 347 | disabled = true 348 | toggle_mode = true 349 | click_on_press = true 350 | enabled_focus_mode = 2 351 | shortcut = null 352 | text = "Commit" 353 | flat = false 354 | 355 | [node name="btnCancel" type="Button" parent="vbox/hboxWFT"] 356 | 357 | hint/tooltip = "Cancel the edits and bring back the original mesh. It will also delete metadata." 358 | focus/ignore_mouse = false 359 | focus/stop_mouse = true 360 | size_flags/horizontal = 2 361 | size_flags/vertical = 2 362 | margin/left = 142.0 363 | margin/top = 0.0 364 | margin/right = 196.0 365 | margin/bottom = 20.0 366 | disabled = true 367 | toggle_mode = true 368 | click_on_press = true 369 | enabled_focus_mode = 2 370 | shortcut = null 371 | text = "Cancel" 372 | flat = false 373 | 374 | [node name="lblSelTools" type="Label" parent="vbox"] 375 | 376 | focus/ignore_mouse = true 377 | focus/stop_mouse = true 378 | size_flags/horizontal = 2 379 | size_flags/vertical = 0 380 | margin/left = 0.0 381 | margin/top = 157.0 382 | margin/right = 201.0 383 | margin/bottom = 171.0 384 | text = "Selection Tools" 385 | percent_visible = 1.0 386 | lines_skipped = 0 387 | max_lines_visible = -1 388 | 389 | [node name="group" type="ButtonGroup" parent="vbox"] 390 | 391 | focus/ignore_mouse = false 392 | focus/stop_mouse = false 393 | size_flags/horizontal = 2 394 | size_flags/vertical = 2 395 | margin/left = 0.0 396 | margin/top = 175.0 397 | margin/right = 201.0 398 | margin/bottom = 219.0 399 | alignment = 0 400 | 401 | [node name="GridContainer" type="GridContainer" parent="vbox/group"] 402 | 403 | focus/ignore_mouse = false 404 | focus/stop_mouse = false 405 | size_flags/horizontal = 2 406 | size_flags/vertical = 2 407 | margin/left = 0.0 408 | margin/top = 0.0 409 | margin/right = 201.0 410 | margin/bottom = 44.0 411 | columns = 3 412 | 413 | [node name="btnNone" type="Button" parent="vbox/group/GridContainer"] 414 | 415 | hint/tooltip = "Plugin won\'t capture the input so you can use spatial gizmos." 416 | focus/ignore_mouse = false 417 | focus/stop_mouse = true 418 | size_flags/horizontal = 2 419 | size_flags/vertical = 2 420 | margin/left = 0.0 421 | margin/top = 0.0 422 | margin/right = 46.0 423 | margin/bottom = 20.0 424 | disabled = true 425 | toggle_mode = true 426 | click_on_press = true 427 | enabled_focus_mode = 2 428 | shortcut = null 429 | text = "None" 430 | flat = false 431 | 432 | [node name="btnVertex" type="Button" parent="vbox/group/GridContainer"] 433 | 434 | hint/tooltip = "Select one vertex." 435 | focus/ignore_mouse = false 436 | focus/stop_mouse = true 437 | size_flags/horizontal = 2 438 | size_flags/vertical = 2 439 | margin/left = 50.0 440 | margin/top = 0.0 441 | margin/right = 110.0 442 | margin/bottom = 20.0 443 | disabled = true 444 | toggle_mode = true 445 | click_on_press = true 446 | enabled_focus_mode = 2 447 | shortcut = null 448 | text = "Vertex" 449 | flat = false 450 | 451 | [node name="btnEdge" type="Button" parent="vbox/group/GridContainer"] 452 | 453 | hint/tooltip = "Select one or multiple edges." 454 | focus/ignore_mouse = false 455 | focus/stop_mouse = true 456 | size_flags/horizontal = 2 457 | size_flags/vertical = 2 458 | margin/left = 114.0 459 | margin/top = 0.0 460 | margin/right = 156.0 461 | margin/bottom = 20.0 462 | disabled = true 463 | toggle_mode = true 464 | click_on_press = true 465 | enabled_focus_mode = 2 466 | shortcut = null 467 | text = "Edge" 468 | flat = false 469 | 470 | [node name="btnLoop" type="Button" parent="vbox/group/GridContainer"] 471 | 472 | visibility/visible = false 473 | hint/tooltip = "Select the loop." 474 | focus/ignore_mouse = false 475 | focus/stop_mouse = true 476 | size_flags/horizontal = 2 477 | size_flags/vertical = 2 478 | margin/left = 0.0 479 | margin/top = 24.0 480 | margin/right = 46.0 481 | margin/bottom = 44.0 482 | disabled = true 483 | toggle_mode = true 484 | click_on_press = true 485 | enabled_focus_mode = 2 486 | shortcut = null 487 | text = "Loop" 488 | flat = false 489 | 490 | [node name="btnAll" type="Button" parent="vbox/group/GridContainer"] 491 | 492 | hint/tooltip = "Select every edge." 493 | focus/ignore_mouse = false 494 | focus/stop_mouse = true 495 | size_flags/horizontal = 2 496 | size_flags/vertical = 2 497 | margin/left = 0.0 498 | margin/top = 24.0 499 | margin/right = 46.0 500 | margin/bottom = 44.0 501 | disabled = true 502 | toggle_mode = true 503 | click_on_press = true 504 | enabled_focus_mode = 2 505 | shortcut = null 506 | text = "All" 507 | flat = false 508 | 509 | [node name="btnInverse" type="Button" parent="vbox/group/GridContainer"] 510 | 511 | hint/tooltip = "Inverse the selection." 512 | focus/ignore_mouse = false 513 | focus/stop_mouse = true 514 | size_flags/horizontal = 2 515 | size_flags/vertical = 2 516 | margin/left = 50.0 517 | margin/top = 24.0 518 | margin/right = 110.0 519 | margin/bottom = 44.0 520 | disabled = true 521 | toggle_mode = true 522 | click_on_press = true 523 | enabled_focus_mode = 2 524 | shortcut = null 525 | text = "Inverse" 526 | flat = false 527 | 528 | [node name="lblActions" type="Label" parent="vbox"] 529 | 530 | focus/ignore_mouse = true 531 | focus/stop_mouse = true 532 | size_flags/horizontal = 2 533 | size_flags/vertical = 0 534 | margin/left = 0.0 535 | margin/top = 223.0 536 | margin/right = 201.0 537 | margin/bottom = 237.0 538 | text = "Actions" 539 | percent_visible = 1.0 540 | lines_skipped = 0 541 | max_lines_visible = -1 542 | 543 | [node name="gridActions" type="HBoxContainer" parent="vbox"] 544 | 545 | focus/ignore_mouse = false 546 | focus/stop_mouse = false 547 | size_flags/horizontal = 2 548 | size_flags/vertical = 2 549 | margin/left = 0.0 550 | margin/top = 241.0 551 | margin/right = 201.0 552 | margin/bottom = 261.0 553 | alignment = 0 554 | 555 | [node name="btnDelete" type="Button" parent="vbox/gridActions"] 556 | 557 | hint/tooltip = "Delete selected vertex or edges." 558 | focus/ignore_mouse = false 559 | focus/stop_mouse = true 560 | size_flags/horizontal = 2 561 | size_flags/vertical = 2 562 | margin/left = 0.0 563 | margin/top = 0.0 564 | margin/right = 55.0 565 | margin/bottom = 20.0 566 | disabled = true 567 | toggle_mode = false 568 | enabled_focus_mode = 2 569 | shortcut = null 570 | text = "Delete" 571 | flat = false 572 | 573 | [node name="btnColor" type="Button" parent="vbox/gridActions"] 574 | 575 | hint/tooltip = "Color the selection with choosen color." 576 | focus/ignore_mouse = false 577 | focus/stop_mouse = true 578 | size_flags/horizontal = 2 579 | size_flags/vertical = 2 580 | margin/left = 59.0 581 | margin/top = 0.0 582 | margin/right = 104.0 583 | margin/bottom = 20.0 584 | disabled = true 585 | toggle_mode = false 586 | enabled_focus_mode = 2 587 | shortcut = null 588 | text = "Color" 589 | flat = false 590 | 591 | [node name="ColorPickerButton" type="ColorPickerButton" parent="vbox/gridActions"] 592 | 593 | rect/min_size = Vector2( 60, 0 ) 594 | hint/tooltip = "Choose the color for action Color." 595 | focus/ignore_mouse = false 596 | focus/stop_mouse = true 597 | size_flags/horizontal = 2 598 | size_flags/vertical = 2 599 | margin/left = 108.0 600 | margin/top = 0.0 601 | margin/right = 168.0 602 | margin/bottom = 20.0 603 | disabled = true 604 | toggle_mode = false 605 | enabled_focus_mode = 2 606 | shortcut = null 607 | flat = false 608 | color = Color( 1, 1, 1, 1 ) 609 | edit_alpha = true 610 | 611 | [node name="lblShaders" type="Label" parent="vbox"] 612 | 613 | focus/ignore_mouse = true 614 | focus/stop_mouse = true 615 | size_flags/horizontal = 2 616 | size_flags/vertical = 0 617 | margin/left = 0.0 618 | margin/top = 265.0 619 | margin/right = 201.0 620 | margin/bottom = 279.0 621 | text = "Materials" 622 | percent_visible = 1.0 623 | lines_skipped = 0 624 | max_lines_visible = -1 625 | 626 | [node name="hboxMaterials" type="HBoxContainer" parent="vbox"] 627 | 628 | focus/ignore_mouse = false 629 | focus/stop_mouse = false 630 | size_flags/horizontal = 2 631 | size_flags/vertical = 2 632 | margin/left = 0.0 633 | margin/top = 283.0 634 | margin/right = 201.0 635 | margin/bottom = 303.0 636 | alignment = 0 637 | 638 | [node name="btnUnlit" type="Button" parent="vbox/hboxMaterials"] 639 | 640 | hint/tooltip = "Set/unset unlit material to surface. This one shows vertex colors and is automatically set after you hit Generate button." 641 | focus/ignore_mouse = false 642 | focus/stop_mouse = true 643 | size_flags/horizontal = 2 644 | size_flags/vertical = 2 645 | margin/left = 0.0 646 | margin/top = 0.0 647 | margin/right = 43.0 648 | margin/bottom = 20.0 649 | disabled = true 650 | toggle_mode = false 651 | enabled_focus_mode = 2 652 | shortcut = null 653 | text = "Unlit" 654 | flat = false 655 | 656 | [node name="btnLit" type="Button" parent="vbox/hboxMaterials"] 657 | 658 | hint/tooltip = "Set/unset lit material to surface which shows vertex colors." 659 | focus/ignore_mouse = false 660 | focus/stop_mouse = true 661 | size_flags/horizontal = 2 662 | size_flags/vertical = 2 663 | margin/left = 47.0 664 | margin/top = 0.0 665 | margin/right = 75.0 666 | margin/bottom = 20.0 667 | disabled = true 668 | toggle_mode = false 669 | enabled_focus_mode = 2 670 | shortcut = null 671 | text = "Lit" 672 | flat = false 673 | 674 | [node name="btnOutline" type="Button" parent="vbox/hboxMaterials"] 675 | 676 | hint/tooltip = "Set/unset outline material to surface. Create a separate wireframe and use this shader on it. Occlude Use it on separate generated wireframe (from FLAT shaded geometry!!) for outline together with occluder geometry." 677 | focus/ignore_mouse = false 678 | focus/stop_mouse = true 679 | size_flags/horizontal = 2 680 | size_flags/vertical = 2 681 | margin/left = 79.0 682 | margin/top = 0.0 683 | margin/right = 123.0 684 | margin/bottom = 20.0 685 | disabled = true 686 | toggle_mode = false 687 | enabled_focus_mode = 2 688 | shortcut = null 689 | text = "Outl." 690 | flat = false 691 | 692 | [node name="btnOccluder" type="Button" parent="vbox/hboxMaterials"] 693 | 694 | focus/ignore_mouse = false 695 | focus/stop_mouse = true 696 | size_flags/horizontal = 2 697 | size_flags/vertical = 2 698 | margin/left = 127.0 699 | margin/top = 0.0 700 | margin/right = 172.0 701 | margin/bottom = 20.0 702 | toggle_mode = false 703 | enabled_focus_mode = 2 704 | shortcut = null 705 | text = "Occl." 706 | flat = false 707 | 708 | [node name="sep2" type="HSeparator" parent="vbox"] 709 | 710 | focus/ignore_mouse = true 711 | focus/stop_mouse = true 712 | size_flags/horizontal = 2 713 | size_flags/vertical = 0 714 | margin/left = 0.0 715 | margin/top = 307.0 716 | margin/right = 201.0 717 | margin/bottom = 310.0 718 | 719 | [node name="btnHelp" type="Button" parent="vbox"] 720 | 721 | focus/ignore_mouse = false 722 | focus/stop_mouse = true 723 | size_flags/horizontal = 2 724 | size_flags/vertical = 2 725 | margin/left = 0.0 726 | margin/top = 314.0 727 | margin/right = 201.0 728 | margin/bottom = 334.0 729 | toggle_mode = false 730 | enabled_focus_mode = 2 731 | shortcut = null 732 | text = "Show help" 733 | flat = false 734 | 735 | [node name="lblWarning" type="Label" parent="vbox"] 736 | 737 | rect/min_size = Vector2( 0, 80 ) 738 | focus/ignore_mouse = true 739 | focus/stop_mouse = true 740 | size_flags/horizontal = 2 741 | size_flags/vertical = 3 742 | margin/left = 0.0 743 | margin/top = 338.0 744 | margin/right = 201.0 745 | margin/bottom = 418.0 746 | custom_colors/font_color = Color( 1, 0.253906, 0.463745, 1 ) 747 | text = "Warnings:" 748 | autowrap = true 749 | percent_visible = 1.0 750 | lines_skipped = 0 751 | max_lines_visible = -1 752 | 753 | [node name="sep3" type="HSeparator" parent="vbox"] 754 | 755 | visibility/visible = false 756 | focus/ignore_mouse = false 757 | focus/stop_mouse = true 758 | size_flags/horizontal = 2 759 | size_flags/vertical = 2 760 | margin/left = 0.0 761 | margin/top = 422.0 762 | margin/right = 201.0 763 | margin/bottom = 425.0 764 | 765 | [node name="lblVertex" type="Label" parent="vbox"] 766 | 767 | visibility/visible = false 768 | focus/ignore_mouse = true 769 | focus/stop_mouse = true 770 | size_flags/horizontal = 2 771 | size_flags/vertical = 0 772 | margin/left = 0.0 773 | margin/top = 429.0 774 | margin/right = 201.0 775 | margin/bottom = 443.0 776 | text = "Vertex Cloud Tool" 777 | percent_visible = 1.0 778 | lines_skipped = 0 779 | max_lines_visible = -1 780 | 781 | 782 | -------------------------------------------------------------------------------- /addons/Wireframe Tool/wireframetool.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends EditorPlugin 3 | 4 | var canEdit = false 5 | var selectedNodes 6 | var dock = preload("res://addons/Wireframe Tool/dock.tscn").instance() 7 | var activeTool = dock.SELECTION_TOOL_EDGES 8 | var editedMaterial = preload("res://addons/Wireframe Tool/materials/editMat.tres") #material for vertex color preview (unshaded) 9 | var helpDialog = preload("res://addons/Wireframe Tool/helpDialog.tscn").instance() 10 | var nameCounter = 0 11 | var edgeSelector = [] 12 | var vertexSelector = -1 13 | 14 | ##################### ENGINE CALLBACKS ############################################# 15 | 16 | func _enter_tree(): 17 | get_selection().connect("selection_changed", self, "selectionChanged") 18 | get_base_control().add_child(helpDialog) 19 | dock.wftScript = self 20 | add_control_to_dock(DOCK_SLOT_RIGHT_BL, dock) 21 | 22 | func _exit_tree(): 23 | get_selection().disconnect("selection_changed", self, "selectionChanged") 24 | get_base_control().remove_child(helpDialog) 25 | helpDialog.free() 26 | remove_control_from_docks(dock) 27 | dock.free() 28 | 29 | func forward_spatial_input_event(camera, event): 30 | if (!canEdit): 31 | return 32 | if (event.type == InputEvent.MOUSE_BUTTON): 33 | if (event.button_index == BUTTON_LEFT and event.pressed): 34 | var targetMesh = selectedNodes[dock.getSelTargetMeshId()].get_mesh() 35 | var surfaceName = dock.getSelTargetSurfaceName() 36 | 37 | if (activeTool == dock.SELECTION_TOOL_NONE): 38 | return 39 | elif (event.alt or activeTool == dock.SELECTION_TOOL_VERTEX): 40 | #vertex selector 41 | var ids = surfaceNameToId(targetMesh, surfaceName) 42 | var meshTool = MeshDataTool.new() 43 | meshTool.create_from_surface(targetMesh.get_meta("orgMesh"), int(ids.y)) 44 | edgeSelector.clear() 45 | var index 46 | var oldDistance = 1000000 47 | 48 | for i in range(meshTool.get_vertex_count()): 49 | if (testEdges(meshTool, i, targetMesh.get_meta("VEL")[surfaceName])): 50 | var vertex = meshTool.get_vertex(i) 51 | vertex = camera.unproject_position(selectedNodes[dock.getSelTargetMeshId()].get_transform().basis * vertex + selectedNodes[dock.getSelTargetMeshId()].get_transform().origin) 52 | var distance = vertex.distance_to(event.pos) 53 | if (distance < oldDistance): 54 | oldDistance = distance 55 | index = i 56 | 57 | if (vertexSelector == index): 58 | vertexSelector = -1 59 | else: 60 | vertexSelector = index 61 | #color picker 62 | if (event.control): 63 | if (meshTool.get_edge_vertex(meshTool.get_vertex_edges(vertexSelector)[0], 0) == vertexSelector): 64 | dock.setColor(targetMesh.get_meta("COL")[surfaceName][meshTool.get_vertex_edges(vertexSelector)[0]*2]) 65 | else: 66 | dock.setColor(targetMesh.get_meta("COL")[surfaceName][meshTool.get_vertex_edges(vertexSelector)[0]*2+1]) 67 | generateWireframeMesh(meshTool, targetMesh, int(ids.x), surfaceName) 68 | return true 69 | elif (activeTool == dock.SELECTION_TOOL_EDGES): 70 | #edge selector 71 | var ids = surfaceNameToId(targetMesh, surfaceName) 72 | var meshTool = MeshDataTool.new() 73 | meshTool.create_from_surface(targetMesh.get_meta("orgMesh"), int(ids.y)) 74 | vertexSelector = -1 75 | var edgeIndex = -1 76 | var oldDistance = 1000000 77 | 78 | for visEdge in targetMesh.get_meta("VEL")[surfaceName]: 79 | var edgePoint1 = meshTool.get_vertex(meshTool.get_edge_vertex(visEdge, 0)) 80 | var edgePoint2 = meshTool.get_vertex(meshTool.get_edge_vertex(visEdge, 1)) 81 | var vertex = edgePoint1.linear_interpolate(edgePoint2, 0.5) 82 | #transform and unproject the points 83 | edgePoint1 = camera.unproject_position(selectedNodes[dock.getSelTargetMeshId()].get_transform().basis * edgePoint1 + selectedNodes[dock.getSelTargetMeshId()].get_transform().origin) 84 | edgePoint2 = camera.unproject_position(selectedNodes[dock.getSelTargetMeshId()].get_transform().basis * edgePoint2 + selectedNodes[dock.getSelTargetMeshId()].get_transform().origin) 85 | var distance = distanceToEdge(edgePoint1, edgePoint2, event.pos) #transform them!! 86 | #TODO 87 | if (distance < oldDistance): 88 | oldDistance = distance 89 | edgeIndex = visEdge 90 | 91 | if (edgeIndex != -1): 92 | if (edgeIndex in edgeSelector): 93 | edgeSelector.erase(edgeIndex) 94 | else: 95 | edgeSelector.append(edgeIndex) 96 | generateWireframeMesh(meshTool, targetMesh, int(ids.x), surfaceName) 97 | return true 98 | elif (activeTool == dock.SELECTION_TOOL_ALL): 99 | selectAll(targetMesh, surfaceName) 100 | return true 101 | elif (activeTool == dock.SELECTION_TOOL_INVERSE): 102 | selectInverse(targetMesh, surfaceName) 103 | return true 104 | elif (event.type == InputEvent.KEY): 105 | if (event.scancode == KEY_D and event.pressed): 106 | deleteSelection() 107 | elif (event.scancode == KEY_C and event.pressed): 108 | colorSelection() 109 | elif (event.scancode == KEY_A and event.pressed): 110 | selectAll(selectedNodes[dock.getSelTargetMeshId()].get_mesh(), dock.getSelTargetSurfaceName()) 111 | elif (event.scancode == KEY_I and event.pressed): 112 | selectInverse(selectedNodes[dock.getSelTargetMeshId()].get_mesh(), dock.getSelTargetSurfaceName()) 113 | return false 114 | 115 | func clear(): 116 | if (selectedNodes != null): 117 | selectedNodes.clear() 118 | 119 | func handles(object): 120 | #this throws a shit ton of errors in console 121 | #and it can't handle multiple selected nodes so far 122 | # yield(get_selection(), "selection_changed") 123 | return object extends MeshInstance 124 | 125 | ########################## SIGNALS ################################ 126 | 127 | func targetMeshSelection(id): 128 | dock.clearSelTargetSurface() 129 | surfaceGUIFill(selectedNodes[id].get_mesh(), true) 130 | surfaceGUITest(selectedNodes[id].get_mesh(), dock.getSelTargetSurfaceName()) 131 | dock.showRenameSurface(false) 132 | 133 | func targetSurfaceSelection(id): 134 | surfaceGUITest(selectedNodes[dock.getSelTargetMeshId()].get_mesh(), dock.getSelTargetSurfaceName()) 135 | dock.showRenameSurface(false) 136 | 137 | func sourceMeshSelection(id): 138 | dock.clearSelSourceSurface() 139 | surfaceGUIFill(selectedNodes[id].get_mesh(), false) 140 | 141 | func renameSurface(): 142 | dock.showRenameSurface(true) 143 | 144 | func renameSurfaceOK(): 145 | if (dock.getRenameSurfaceText() == dock.getSelTargetSurfaceName() or dock.getRenameSurfaceText() == ""): 146 | dock.setWarning("Surface wasn't renamed.") 147 | dock.showRenameSurface(false) 148 | return 149 | var targetMesh = selectedNodes[dock.getSelTargetMeshId()].get_mesh() 150 | var sId = -1 151 | var sIdOrgMesh = -1 152 | var oldName = dock.getSelTargetSurfaceName() 153 | var newName = dock.getRenameSurfaceText() 154 | #find old surfaces in mesh and metadata, also test against collisions 155 | for i in range(targetMesh.get_surface_count()): 156 | if (newName == targetMesh.surface_get_name(i)): 157 | dock.setWarning("Some surface in target has same name. Please choose an unique name.") 158 | return 159 | if (oldName == targetMesh.surface_get_name(i)): 160 | sId = i 161 | if (targetMesh.has_meta("orgMesh")): 162 | if (i < targetMesh.get_meta("orgMesh").get_surface_count()): 163 | if (oldName == targetMesh.get_meta("orgMesh").surface_get_name(i)): 164 | sIdOrgMesh = i 165 | if (sId != -1): 166 | targetMesh.surface_set_name(sId, newName) 167 | if (sIdOrgMesh != -1): 168 | targetMesh.get_meta("orgMesh").surface_set_name(sIdOrgMesh, newName) 169 | targetMesh.get_meta("VEL")[newName] = targetMesh.get_meta("VEL")[oldName] 170 | targetMesh.get_meta("VEL").erase(oldName) 171 | targetMesh.get_meta("COL")[newName] = targetMesh.get_meta("COL")[oldName] 172 | targetMesh.get_meta("COL").erase(oldName) 173 | dock.showRenameSurface(false) 174 | dock.clearSelTargetSurface() 175 | dock.clearSelSourceSurface() 176 | surfaceGUIFill(targetMesh, true) 177 | if (selectedNodes.size() > 1): 178 | surfaceGUIFill(selectedNodes[dock.getSelSourceMeshId()].get_mesh(), false) 179 | surfaceGUITest(targetMesh, dock.getSelTargetSurfaceName()) 180 | 181 | #TODO this throws errors but works so don't touch 182 | func deleteSurface(): 183 | dock.showRenameSurface(false) 184 | var targetMesh = selectedNodes[dock.getSelTargetMeshId()].get_mesh() 185 | var ids = surfaceNameToId(targetMesh, dock.getSelTargetSurfaceName()) 186 | targetMesh.surface_remove(int(ids.x)) 187 | #delete meta 188 | if (targetMesh.has_meta("orgMesh")): 189 | targetMesh.get_meta("orgMesh").surface_remove(int(ids.y)) 190 | targetMesh.get_meta("VEL").erase(dock.getSelTargetSurfaceName()) 191 | targetMesh.get_meta("COL").erase(dock.getSelTargetSurfaceName()) 192 | if (targetMesh.get_meta("orgMesh").get_surface_count() == 0): 193 | targetMesh.set_meta("orgMesh", null) 194 | targetMesh.set_meta("VEL", null) 195 | targetMesh.set_meta("COL", null) 196 | 197 | dock.clearSelTargetSurface() 198 | surfaceGUIFill(targetMesh, true) 199 | surfaceGUITest(targetMesh, dock.getSelTargetSurfaceName()) 200 | 201 | func copySurface(): 202 | dock.showRenameSurface(false) 203 | var sourceMesh = selectedNodes[dock.getSelSourceMeshId()].get_mesh() 204 | var targetMesh = selectedNodes[dock.getSelTargetMeshId()].get_mesh() 205 | if (sourceMesh == targetMesh): 206 | dock.setWarning("Target and source meshes are same. Can't copy!") 207 | return 208 | #find surface in source 209 | var surfaceName = dock.getSelSourceSurfaceName() 210 | var ids = surfaceNameToId(sourceMesh, surfaceName) 211 | #the name can't collide in target 212 | for i in range(targetMesh.get_surface_count()): 213 | if (surfaceName == targetMesh.surface_get_name(i)): 214 | dock.setWarning("Some surface in target has same name as selected source surface. Can't copy!") 215 | return 216 | #no collision 217 | if (sourceMesh.has_meta("orgMesh")): 218 | if (int(ids.y) != -1): 219 | dock.setWarning("Source surface can't be wireframe (not my fault). Can't copy!") 220 | return 221 | var meshTool = MeshDataTool.new() 222 | meshTool.create_from_surface(sourceMesh, int(ids.x)) 223 | meshTool.commit_to_surface(targetMesh) 224 | #find the new surface and rename him 225 | targetMesh.surface_set_name(targetMesh.get_surface_count() - 1, surfaceName) 226 | targetMesh.surface_set_material(targetMesh.get_surface_count() - 1, sourceMesh.surface_get_material(int(ids.x))) 227 | dock.setWarning("Copied.") 228 | #MeshDataTool can't use PRIMITIVE_LINES 229 | # #copy metadata 230 | # if (sourceMesh.has_meta("orgMesh")): 231 | # var mt = MeshDataTool.new() 232 | # mt.create_from_surface(sourceMesh.get_meta("orgMesh"), int(ids.y)) 233 | # if (targetMesh.has_meta("orgMesh")): 234 | # mt.commit_to_surface(targetMesh.get_meta("orgMesh")) 235 | # targetMesh.get_meta("orgMesh").surface_set_name(targetMesh.get_meta("orgMesh").get_surface_count() - 1, surfaceName) 236 | # targetMesh.get_meta("VEL")[surfaceName] = [] + sourceMesh.get_meta("VEL")[surfaceName] 237 | # targetMesh.get_meta("COL")[surfaceName] = [] + sourceMesh.get_meta("COL")[surfaceName] 238 | # else: 239 | # var newMesh = Mesh.new() 240 | # mt.commit_to_surface(newMesh) 241 | # newMesh.surface_set_name(0, surfaceName) 242 | # targetMesh.set_meta("orgMesh", newMesh) 243 | # targetMesh.set_meta("VEL", [] + sourceMesh.get_meta("VEL")[surfaceName]) 244 | # targetMesh.set_meta("COL", [] + sourceMesh.get_meta("COL")[surfaceName]) 245 | #refresh target surface selection 246 | dock.clearSelTargetSurface() 247 | surfaceGUIFill(targetMesh, true) 248 | surfaceGUITest(targetMesh, dock.getSelTargetSurfaceName()) 249 | 250 | func generateWirefame(): 251 | if (isMeshInvalid(selectedNodes[dock.getSelTargetMeshId()])): 252 | return 253 | var targetMesh = selectedNodes[dock.getSelTargetMeshId()].get_mesh() 254 | var surfaceName = dock.getSelTargetSurfaceName() 255 | 256 | var undoRedo = get_undo_redo() 257 | undoRedo.create_action("WFT Generate") 258 | undoRedo.add_do_method(self, "doGenerateWireframe", targetMesh, surfaceName) 259 | #doCancel is same as undoGenerate 260 | undoRedo.add_undo_method(self, "doCancelWireframe", selectedNodes[dock.getSelTargetMeshId()], targetMesh, surfaceName) 261 | undoRedo.commit_action() 262 | 263 | func commitWireframe(): 264 | var surfaceName = dock.getSelTargetSurfaceName() 265 | var mesh = selectedNodes[dock.getSelTargetMeshId()].get_mesh() 266 | var delArray = [] + mesh.get_meta("VEL")[surfaceName] 267 | var colArray = [] + mesh.get_meta("COL")[surfaceName] 268 | var meshTool = MeshDataTool.new() 269 | meshTool.create_from_surface(mesh.get_meta("orgMesh"), int(surfaceNameToId(mesh, surfaceName).y)) 270 | 271 | var undoRedo = get_undo_redo() 272 | undoRedo.create_action("WFT Commit") 273 | undoRedo.add_do_method(self, "doCommitWireframe", selectedNodes[dock.getSelTargetMeshId()], mesh, surfaceName) 274 | undoRedo.add_undo_method(self, "undoCommitWireframe", mesh, surfaceName, delArray, meshTool, colArray) 275 | undoRedo.commit_action() 276 | 277 | func cancelWireframe(): 278 | if (isMeshInvalid(selectedNodes[dock.getSelTargetMeshId()])): 279 | return 280 | var surfaceName = dock.getSelTargetSurfaceName() 281 | var mesh = selectedNodes[dock.getSelTargetMeshId()].get_mesh() 282 | var delArray = [] + mesh.get_meta("VEL")[surfaceName] 283 | var colArray = [] + mesh.get_meta("COL")[surfaceName] 284 | var meshTool = MeshDataTool.new() 285 | meshTool.create_from_surface(mesh.get_meta("orgMesh"), int(surfaceNameToId(mesh, surfaceName).y)) 286 | 287 | var undoRedo = get_undo_redo() 288 | undoRedo.create_action("WFT Cancel") 289 | undoRedo.add_do_method(self, "doCancelWireframe", selectedNodes[dock.getSelTargetMeshId()], mesh, surfaceName) 290 | undoRedo.add_undo_method(self, "undoCancelWireframe", mesh, surfaceName, delArray, meshTool, colArray) 291 | undoRedo.commit_action() 292 | 293 | func selectionChanged(): 294 | dock.showRenameSurface(false) 295 | dock.setWarning("") 296 | selectedNodes = get_selection().get_selected_nodes() 297 | edgeSelector.clear() 298 | vertexSelector = -1 299 | dock.clearSelTargetMesh() 300 | dock.clearSelSourceMesh() 301 | dock.clearSelTargetSurface() 302 | dock.clearSelSourceSurface() 303 | var i = -1 304 | var validNodes = 0 305 | for node in selectedNodes: 306 | i += 1 307 | if (node extends MeshInstance): 308 | if (!isMeshInvalid(node)): #mesh is valid, add it to target and source 309 | dock.setTargetMeshName(node.get_name(), i) 310 | dock.setSourceMeshName(node.get_name(), i) 311 | validNodes += 1 312 | #we filled target and source with valid MI nodes 313 | if (validNodes == 0): #no valid node, disable all and return 314 | dock.setWarning("%s No valid node selected." % dock.getWarning()) 315 | dock.cleanAndLock() 316 | canEdit = false 317 | return 318 | elif (validNodes == 1): #one node - disable copy, enable target 319 | dock.setWarning("One valid node selected.") 320 | dock.clearSelSourceMesh() 321 | dock.disableSurfaceCopy(true) 322 | dock.disableTarget(false) 323 | elif (validNodes > 1): #more than one node, enable copy and target, remove sel. target mesh from source mesh list 324 | dock.setWarning("%d valid nodes selected." % validNodes) 325 | dock.disableSurfaceCopy(false) 326 | dock.disableTarget(false) 327 | surfaceGUIFill(selectedNodes[dock.getSelSourceMeshId()].get_mesh(), false) #fill source surface list 328 | surfaceGUIFill(selectedNodes[dock.getSelTargetMeshId()].get_mesh(), true) 329 | #surfaces are filled, test the selected one 330 | return surfaceGUITest(selectedNodes[dock.getSelTargetMeshId()].get_mesh(), dock.getSelTargetSurfaceName()) 331 | 332 | func deleteSelection(): 333 | #delete vertex - just put edges to edgeSelector 334 | if (vertexSelector != -1): 335 | var targetMesh = selectedNodes[dock.getSelTargetMeshId()].get_mesh() 336 | var meshTool = MeshDataTool.new() 337 | var ids = surfaceNameToId(targetMesh, dock.getSelTargetSurfaceName()) 338 | var meshTool = MeshDataTool.new() 339 | meshTool.create_from_surface(targetMesh.get_meta("orgMesh"), int(ids.y)) 340 | 341 | for edgeIndex in meshTool.get_vertex_edges(vertexSelector): 342 | edgeSelector.append(edgeIndex) 343 | 344 | vertexSelector = -1 345 | 346 | if (edgeSelector.size() > 0): 347 | var targetMesh = selectedNodes[dock.getSelTargetMeshId()].get_mesh() 348 | var undoRedo = get_undo_redo() 349 | undoRedo.create_action("WFT Delete Edges") 350 | undoRedo.add_do_method(self, "doDeleteEdges", [] + edgeSelector, targetMesh, dock.getSelTargetSurfaceName()) 351 | undoRedo.add_undo_method(self, "undoDeleteEdges", [] + edgeSelector, targetMesh, dock.getSelTargetSurfaceName()) 352 | undoRedo.commit_action() 353 | edgeSelector.clear() 354 | 355 | #TODO undo/redo 356 | func colorSelection(): 357 | if (edgeSelector.size() > 0): 358 | var mesh = selectedNodes[dock.getSelTargetMeshId()].get_mesh() 359 | var surfaceName = dock.getSelTargetSurfaceName() 360 | var ids = surfaceNameToId(mesh, surfaceName) 361 | var meshTool = MeshDataTool.new() 362 | meshTool.create_from_surface(mesh.get_meta("orgMesh"), int(ids.y)) 363 | 364 | for edge in edgeSelector: 365 | mesh.get_meta("COL")[surfaceName][edge*2] = dock.getColor() 366 | mesh.get_meta("COL")[surfaceName][edge*2+1] = dock.getColor() 367 | 368 | generateWireframeMesh(meshTool, mesh, int(ids.x), surfaceName) 369 | 370 | elif (vertexSelector != -1): 371 | var mesh = selectedNodes[dock.getSelTargetMeshId()].get_mesh() 372 | var surfaceName = dock.getSelTargetSurfaceName() 373 | var ids = surfaceNameToId(mesh, surfaceName) 374 | var meshTool = MeshDataTool.new() 375 | meshTool.create_from_surface(mesh.get_meta("orgMesh"), int(ids.y)) 376 | 377 | for edge in meshTool.get_vertex_edges(vertexSelector): 378 | if (meshTool.get_edge_vertex(edge, 0) == vertexSelector): 379 | mesh.get_meta("COL")[surfaceName][edge*2] = dock.getColor() 380 | else: 381 | mesh.get_meta("COL")[surfaceName][edge*2+1] = dock.getColor() 382 | 383 | generateWireframeMesh(meshTool, mesh, int(ids.x), surfaceName) 384 | 385 | func setUnlitShader(): 386 | if (isMeshInvalid(selectedNodes[dock.getSelTargetMeshId()])): 387 | return 388 | var ids = surfaceNameToId(selectedNodes[dock.getSelTargetMeshId()].get_mesh(), dock.getSelTargetSurfaceName()) 389 | selectedNodes[dock.getSelTargetMeshId()].get_mesh().surface_set_material(int(ids.x), editedMaterial) 390 | 391 | func setLitShader(): 392 | if (isMeshInvalid(selectedNodes[dock.getSelTargetMeshId()])): 393 | return 394 | var ids = surfaceNameToId(selectedNodes[dock.getSelTargetMeshId()].get_mesh(), dock.getSelTargetSurfaceName()) 395 | selectedNodes[dock.getSelTargetMeshId()].get_mesh().surface_set_material(int(ids.x), load("res://addons/Wireframe Tool/materials/litMat.tres")) 396 | 397 | func setOutlineShader(): 398 | if (isMeshInvalid(selectedNodes[dock.getSelTargetMeshId()])): 399 | return 400 | var ids = surfaceNameToId(selectedNodes[dock.getSelTargetMeshId()].get_mesh(), dock.getSelTargetSurfaceName()) 401 | selectedNodes[dock.getSelTargetMeshId()].get_mesh().surface_set_material(int(ids.x), load("res://addons/Wireframe Tool/materials/outlineMat.tres")) 402 | 403 | func setOccluderShader(): 404 | if (isMeshInvalid(selectedNodes[dock.getSelTargetMeshId()])): 405 | return 406 | var ids = surfaceNameToId(selectedNodes[dock.getSelTargetMeshId()].get_mesh(), dock.getSelTargetSurfaceName()) 407 | selectedNodes[dock.getSelTargetMeshId()].get_mesh().surface_set_material(int(ids.x), load("res://addons/Wireframe Tool/materials/occluderMat.tres")) 408 | 409 | func showHelp(): 410 | helpDialog.popup_centered() 411 | 412 | ###################### HELPER FUNCTIONS ##################################### 413 | 414 | func generateWireframeMesh(meshTool, mesh, surfaceId, surfaceName): 415 | var surfaceTool = SurfaceTool.new() 416 | surfaceTool.begin(Mesh.PRIMITIVE_LINES) 417 | 418 | for visEdge in mesh.get_meta("VEL")[surfaceName]: 419 | if (visEdge in edgeSelector or vertexSelector == meshTool.get_edge_vertex(visEdge, 0)): 420 | surfaceTool.add_color(mesh.get_meta("COL")[surfaceName][visEdge*2].inverted()) 421 | else: 422 | surfaceTool.add_color(mesh.get_meta("COL")[surfaceName][visEdge*2]) 423 | 424 | surfaceTool.add_normal(meshTool.get_vertex_normal(meshTool.get_edge_vertex(visEdge, 0))) 425 | #FIXME - not sure if those two are connected but I'm too lazy to test it 426 | if (meshTool.get_vertex_bones(meshTool.get_edge_vertex(visEdge, 0)).size() != 0): 427 | surfaceTool.add_weights(meshTool.get_vertex_weights(meshTool.get_edge_vertex(visEdge, 0))) 428 | surfaceTool.add_bones(meshTool.get_vertex_bones(meshTool.get_edge_vertex(visEdge, 0))) 429 | surfaceTool.add_uv(meshTool.get_vertex_uv(meshTool.get_edge_vertex(visEdge, 0))) 430 | surfaceTool.add_vertex(meshTool.get_vertex(meshTool.get_edge_vertex(visEdge, 0))) 431 | 432 | if (visEdge in edgeSelector or vertexSelector == meshTool.get_edge_vertex(visEdge, 1)): 433 | surfaceTool.add_color(mesh.get_meta("COL")[surfaceName][visEdge*2+1].inverted()) 434 | else: 435 | surfaceTool.add_color(mesh.get_meta("COL")[surfaceName][visEdge*2+1]) 436 | 437 | surfaceTool.add_normal(meshTool.get_vertex_normal(meshTool.get_edge_vertex(visEdge, 1))) 438 | if (meshTool.get_vertex_bones(meshTool.get_edge_vertex(visEdge, 1)).size() != 0): 439 | surfaceTool.add_weights(meshTool.get_vertex_weights(meshTool.get_edge_vertex(visEdge, 1))) 440 | surfaceTool.add_bones(meshTool.get_vertex_bones(meshTool.get_edge_vertex(visEdge, 1))) 441 | surfaceTool.add_uv(meshTool.get_vertex_uv(meshTool.get_edge_vertex(visEdge, 1))) 442 | surfaceTool.add_vertex(meshTool.get_vertex(meshTool.get_edge_vertex(visEdge, 1))) 443 | 444 | var oldMat = mesh.surface_get_material(surfaceId) 445 | mesh.surface_set_material(surfaceId, null) 446 | mesh.surface_remove(surfaceId) 447 | surfaceTool.commit(mesh) 448 | mesh.surface_set_name(mesh.get_surface_count() - 1, surfaceName) 449 | mesh.surface_set_material(mesh.get_surface_count() - 1, oldMat) 450 | 451 | #fill surface list from mesh - if isTarget = false -> it's source, do name check 452 | func surfaceGUIFill(mesh, isTarget): 453 | var renSurCount = 0 454 | for i in range(mesh.get_surface_count()): 455 | if (mesh.surface_get_name(i) == ""): 456 | renSurCount += 1 457 | dock.setWarning("Found %d surface(s) without name! Every surface needs to have an unique name. I named them for you." % renSurCount) 458 | mesh.surface_set_name(i, "sur_%d" % nameCounter) 459 | nameCounter += 1 460 | if (isTarget): 461 | dock.setTargetSurfaceName(mesh.surface_get_name(i)) 462 | else: 463 | dock.setSourceSurfaceName(mesh.surface_get_name(i)) 464 | 465 | #test if surface is in metadata - to set the GUI 466 | func surfaceGUITest(mesh, surfaceName): 467 | if (mesh.has_meta("orgMesh")): #we can't assume the mesh was edited by this tool before 468 | for i in range(mesh.get_meta("orgMesh").get_surface_count()): 469 | if (mesh.get_meta("orgMesh").surface_get_name(i) == surfaceName): #we find selected surface in metadata 470 | dock.disableWFT(false) #turn on tools 471 | canEdit = true 472 | return 473 | dock.disableWFT(true) 474 | canEdit = false 475 | return 476 | else: #no meta find, there's no surface to look for 477 | dock.disableWFT(true) 478 | canEdit = false 479 | return 480 | 481 | #find surface id in mesh and metadata orgMest TODO add this where needed 482 | func surfaceNameToId(mesh, name): 483 | var ids = Vector2(-1, -1) 484 | for i in range(mesh.get_surface_count()): 485 | if (mesh.surface_get_name(i) == name): 486 | ids.x = float(i) 487 | if (mesh.has_meta("orgMesh")): 488 | if (i < mesh.get_meta("orgMesh").get_surface_count()): 489 | if (name == mesh.get_meta("orgMesh").surface_get_name(i)): 490 | ids.y = float(i) 491 | return ids 492 | 493 | #tests if the vertex edges are on the list of deleted edges 494 | func testEdges(meshTool, vertexIndex, arrayVEL): 495 | var edges = meshTool.get_vertex_edges(vertexIndex) 496 | for edgeIndex in edges: 497 | if (edgeIndex in arrayVEL): 498 | return true 499 | return false 500 | 501 | #find closest line segment 502 | func distanceToEdge(edgePoint1, edgePoint2, point): 503 | var l2 = edgePoint1.distance_squared_to(edgePoint2) 504 | var pe1 = point - edgePoint1 505 | var t = max(0.0, min(1.0, pe1.dot(edgePoint2 - edgePoint1) / l2)) 506 | var projection = edgePoint1 + t * (edgePoint2 - edgePoint1) 507 | return point.distance_to(projection) 508 | 509 | func isMeshInvalid(meshInstance): 510 | if (meshInstance.get_mesh() == null): 511 | dock.setWarning("Selected MeshInstance doesn't have Mesh property!") 512 | return true 513 | elif (meshInstance.get_mesh().get_surface_count() == 0): 514 | dock.setWarning("Mesh doesn't have any surface!") 515 | return true 516 | else: 517 | return false 518 | 519 | func selectAll(targetMesh, surfaceName): 520 | var ids = surfaceNameToId(targetMesh, surfaceName) 521 | var meshTool = MeshDataTool.new() 522 | meshTool.create_from_surface(targetMesh.get_meta("orgMesh"), int(ids.y)) 523 | vertexSelector = -1 524 | 525 | if (edgeSelector.size() == targetMesh.get_meta("VEL")[surfaceName].size()): 526 | edgeSelector.clear() 527 | generateWireframeMesh(meshTool, targetMesh, int(ids.x), surfaceName) 528 | return 529 | for visEdge in targetMesh.get_meta("VEL")[surfaceName]: 530 | if (! visEdge in edgeSelector): 531 | edgeSelector.append(visEdge) 532 | generateWireframeMesh(meshTool, targetMesh, int(ids.x), surfaceName) 533 | 534 | func selectInverse(targetMesh, surfaceName): 535 | var ids = surfaceNameToId(targetMesh, surfaceName) 536 | var meshTool = MeshDataTool.new() 537 | meshTool.create_from_surface(targetMesh.get_meta("orgMesh"), int(ids.y)) 538 | vertexSelector = -1 539 | 540 | for visEdge in targetMesh.get_meta("VEL")[surfaceName]: 541 | if (visEdge in edgeSelector): 542 | edgeSelector.erase(visEdge) 543 | else: 544 | edgeSelector.append(visEdge) 545 | generateWireframeMesh(meshTool, targetMesh, int(ids.x), surfaceName) 546 | 547 | ############################ UNDO/REDO ######################################## 548 | 549 | func doDeleteEdges(arrayEdges, mesh, surfaceName): 550 | for edge in arrayEdges: 551 | mesh.get_meta("VEL")[surfaceName].erase(edge) 552 | 553 | var ids = surfaceNameToId(mesh, surfaceName) 554 | var meshTool = MeshDataTool.new() 555 | meshTool.create_from_surface(mesh.get_meta("orgMesh"), int(ids.y)) 556 | generateWireframeMesh(meshTool, mesh, int(ids.x), surfaceName) 557 | 558 | func undoDeleteEdges(arrayEdges, mesh, surfaceName): 559 | for edge in arrayEdges: 560 | mesh.get_meta("VEL")[surfaceName].append(edge) 561 | 562 | var ids = surfaceNameToId(mesh, surfaceName) 563 | var meshTool = MeshDataTool.new() 564 | meshTool.create_from_surface(mesh.get_meta("orgMesh"), int(ids.y)) 565 | generateWireframeMesh(meshTool, mesh, int(ids.x), surfaceName) 566 | 567 | func doCommitWireframe(meshInstance, targetMesh, surfaceName): 568 | if (isMeshInvalid(meshInstance)): 569 | return 570 | var ids = surfaceNameToId(targetMesh, surfaceName) 571 | var meshTool = MeshDataTool.new() 572 | meshTool.create_from_surface(targetMesh.get_meta("orgMesh"), int(ids.y)) 573 | vertexSelector = -1 574 | edgeSelector.clear() 575 | generateWireframeMesh(meshTool, targetMesh, int(ids.x), surfaceName) 576 | 577 | targetMesh.get_meta("orgMesh").surface_remove(int(ids.y)) 578 | targetMesh.get_meta("VEL").erase(surfaceName) 579 | targetMesh.get_meta("COL").erase(surfaceName) 580 | targetMesh.surface_set_material(int(ids.x), null) 581 | 582 | if (targetMesh.get_meta("orgMesh").get_surface_count() == 0): 583 | targetMesh.set_meta("orgMesh", null) 584 | targetMesh.set_meta("VEL", null) 585 | targetMesh.set_meta("COL", null) 586 | 587 | surfaceGUITest(targetMesh, surfaceName) 588 | 589 | func undoCommitWireframe(targetMesh, surfaceName, velArray, meshTool, colArray): 590 | if (!targetMesh.has_meta("orgMesh")): 591 | var nm = Mesh.new() 592 | meshTool.commit_to_surface(nm) 593 | nm.surface_set_name(0, surfaceName) 594 | 595 | targetMesh.set_meta("COL", {surfaceName: colArray}) 596 | targetMesh.set_meta("VEL", {surfaceName: velArray}) 597 | targetMesh.set_meta("orgMesh", nm) 598 | else: 599 | meshTool.commit_to_surface(targetMesh.get_meta("orgMesh")) 600 | targetMesh.get_meta("orgMesh").surface_set_name(targetMesh.get_meta("orgMesh").get_surface_count() - 1, surfaceName) 601 | targetMesh.get_meta("VEL")[surfaceName] = velArray 602 | targetMesh.get_meta("COL")[surfaceName] = colArray 603 | 604 | var ids = surfaceNameToId(targetMesh, surfaceName) 605 | targetMesh.surface_set_material(int(ids.x), editedMaterial) 606 | surfaceGUITest(selectedNodes[dock.getSelSourceMeshId()].get_mesh(), dock.getSelTargetSurfaceName()) 607 | 608 | func doCancelWireframe(meshInstance, targetMesh, surfaceName): 609 | var ids = surfaceNameToId(targetMesh, surfaceName) 610 | var meshTool = MeshDataTool.new() 611 | meshTool.create_from_surface(targetMesh.get_meta("orgMesh"), int(ids.y)) 612 | 613 | for i in range(meshTool.get_vertex_count()): 614 | meshTool.set_vertex_color(i, Color(0.0, 0.0, 0.0)) 615 | #mesh 616 | targetMesh.surface_remove(int(ids.x)) 617 | meshTool.commit_to_surface(targetMesh) 618 | targetMesh.surface_set_name(targetMesh.get_surface_count() - 1, surfaceName) 619 | #meta mesh 620 | targetMesh.get_meta("orgMesh").surface_remove(int(ids.y)) 621 | targetMesh.get_meta("VEL").erase(surfaceName) 622 | targetMesh.get_meta("COL").erase(surfaceName) 623 | 624 | if (targetMesh.get_meta("orgMesh").get_surface_count() == 0): 625 | targetMesh.set_meta("orgMesh", null) 626 | targetMesh.set_meta("VEL", null) 627 | targetMesh.set_meta("COL", null) 628 | 629 | surfaceGUITest(targetMesh, surfaceName) 630 | 631 | func undoCancelWireframe(targetMesh, surfaceName, delArray, meshTool, colArray): 632 | undoCommitWireframe(targetMesh, surfaceName, delArray, meshTool, colArray) 633 | var ids = surfaceNameToId(targetMesh, surfaceName) 634 | generateWireframeMesh(meshTool, targetMesh, int(ids.x), surfaceName) 635 | 636 | func doGenerateWireframe(targetMesh, surfaceName): 637 | var ids = surfaceNameToId(targetMesh, surfaceName) 638 | var meshTool = MeshDataTool.new() 639 | meshTool.create_from_surface(targetMesh, int(ids.x)) 640 | #fill COL with vertex colors - we won't use VC in mesh anymore, fil VEL 641 | var colorArray = [] 642 | var visibleEdges = [] 643 | for i in range(meshTool.get_edge_count()): 644 | visibleEdges.append(i) 645 | colorArray.append(meshTool.get_vertex_color(meshTool.get_edge_vertex(i, 0))) 646 | colorArray.append(meshTool.get_vertex_color(meshTool.get_edge_vertex(i, 1))) 647 | #mesh wasn't edited before - new mesh and commit backup to it, create metadata, add VEL array to dict 648 | if (!targetMesh.has_meta("orgMesh")): 649 | var backupMesh = Mesh.new() 650 | meshTool.commit_to_surface(backupMesh) 651 | backupMesh.surface_set_name(0, surfaceName) 652 | targetMesh.set_meta("orgMesh", backupMesh) 653 | targetMesh.set_meta("VEL", {surfaceName : visibleEdges}) #Dictionary - key: surface name, value: array of int 654 | targetMesh.set_meta("COL", {surfaceName : colorArray}) #value: array - index: edge index, value: color 655 | #mesh has metadata 656 | else: 657 | meshTool.commit_to_surface(targetMesh.get_meta("orgMesh")) 658 | targetMesh.get_meta("orgMesh").surface_set_name(targetMesh.get_meta("orgMesh").get_surface_count() - 1, surfaceName) 659 | targetMesh.get_meta("VEL")[surfaceName] = visibleEdges 660 | targetMesh.get_meta("COL")[surfaceName] = colorArray 661 | 662 | generateWireframeMesh(meshTool, targetMesh, int(ids.x), surfaceName) 663 | targetMesh.surface_set_material(int(ids.x), editedMaterial) 664 | surfaceGUITest(targetMesh, surfaceName) --------------------------------------------------------------------------------