2023-01-10 15:26:54 +01:00
/**************************************************************************/
/* mesh_instance_editor_plugin.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-01-05 00:50:27 +01:00
2016-05-23 22:10:26 +02:00
# include "mesh_instance_editor_plugin.h"
2019-12-24 08:17:23 +01:00
# include "editor/editor_scale.h"
2017-07-15 06:23:10 +02:00
# include "scene/3d/collision_shape.h"
2021-12-16 06:15:23 +01:00
# include "scene/3d/navigation_mesh_instance.h"
2017-03-05 16:44:50 +01:00
# include "scene/3d/physics_body.h"
# include "scene/gui/box_container.h"
2016-05-23 22:10:26 +02:00
# include "spatial_editor_plugin.h"
void MeshInstanceEditor : : _node_removed ( Node * p_node ) {
2017-03-05 16:44:50 +01:00
if ( p_node = = node ) {
2021-05-04 16:00:45 +02:00
node = nullptr ;
2016-05-23 22:10:26 +02:00
options - > hide ( ) ;
}
}
void MeshInstanceEditor : : edit ( MeshInstance * p_mesh ) {
2017-03-05 16:44:50 +01:00
node = p_mesh ;
2016-05-23 22:10:26 +02:00
}
void MeshInstanceEditor : : _menu_option ( int p_option ) {
Ref < Mesh > mesh = node - > get_mesh ( ) ;
if ( mesh . is_null ( ) ) {
err_dialog - > set_text ( TTR ( " Mesh is empty! " ) ) ;
err_dialog - > popup_centered_minsize ( ) ;
return ;
}
2017-03-05 16:44:50 +01:00
switch ( p_option ) {
2020-01-31 16:30:27 +01:00
case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY : {
2016-05-23 22:10:26 +02:00
EditorSelection * editor_selection = EditorNode : : get_singleton ( ) - > get_editor_selection ( ) ;
UndoRedo * ur = EditorNode : : get_singleton ( ) - > get_undo_redo ( ) ;
2017-03-05 16:44:50 +01:00
List < Node * > selection = editor_selection - > get_selected_node_list ( ) ;
2016-05-23 22:10:26 +02:00
if ( selection . empty ( ) ) {
2020-01-31 16:30:27 +01:00
Ref < Shape > shape = mesh - > create_trimesh_shape ( ) ;
if ( shape . is_null ( ) ) {
err_dialog - > set_text ( TTR ( " Couldn't create a Trimesh collision shape. " ) ) ;
err_dialog - > popup_centered_minsize ( ) ;
2016-05-23 22:10:26 +02:00
return ;
2020-01-31 16:30:27 +01:00
}
2016-05-23 22:10:26 +02:00
2017-03-05 16:44:50 +01:00
CollisionShape * cshape = memnew ( CollisionShape ) ;
2016-05-23 22:10:26 +02:00
cshape - > set_shape ( shape ) ;
2017-03-05 16:44:50 +01:00
StaticBody * body = memnew ( StaticBody ) ;
2016-05-23 22:10:26 +02:00
body - > add_child ( cshape ) ;
2022-10-20 09:06:17 +02:00
Node * owner = get_tree ( ) - > get_edited_scene_root ( ) ;
2016-05-23 22:10:26 +02:00
2020-01-31 16:30:27 +01:00
ur - > create_action ( TTR ( " Create Static Trimesh Body " ) ) ;
2017-03-05 16:44:50 +01:00
ur - > add_do_method ( node , " add_child " , body ) ;
ur - > add_do_method ( body , " set_owner " , owner ) ;
ur - > add_do_method ( cshape , " set_owner " , owner ) ;
2016-05-23 22:10:26 +02:00
ur - > add_do_reference ( body ) ;
2017-03-05 16:44:50 +01:00
ur - > add_undo_method ( node , " remove_child " , body ) ;
2016-05-23 22:10:26 +02:00
ur - > commit_action ( ) ;
return ;
}
2019-04-10 22:46:04 +02:00
ur - > create_action ( TTR ( " Create Static Trimesh Body " ) ) ;
2016-05-23 22:10:26 +02:00
2017-03-05 16:44:50 +01:00
for ( List < Node * > : : Element * E = selection . front ( ) ; E ; E = E - > next ( ) ) {
2017-08-24 22:58:51 +02:00
MeshInstance * instance = Object : : cast_to < MeshInstance > ( E - > get ( ) ) ;
2021-05-05 12:44:11 +02:00
if ( ! instance ) {
2016-05-23 22:10:26 +02:00
continue ;
2021-05-05 12:44:11 +02:00
}
2016-05-23 22:10:26 +02:00
Ref < Mesh > m = instance - > get_mesh ( ) ;
2021-05-05 12:44:11 +02:00
if ( m . is_null ( ) ) {
2016-05-23 22:10:26 +02:00
continue ;
2021-05-05 12:44:11 +02:00
}
2016-05-23 22:10:26 +02:00
2020-01-31 16:30:27 +01:00
Ref < Shape > shape = m - > create_trimesh_shape ( ) ;
2021-05-05 12:44:11 +02:00
if ( shape . is_null ( ) ) {
2016-05-23 22:10:26 +02:00
continue ;
2021-05-05 12:44:11 +02:00
}
2016-05-23 22:10:26 +02:00
2017-03-05 16:44:50 +01:00
CollisionShape * cshape = memnew ( CollisionShape ) ;
2016-05-23 22:10:26 +02:00
cshape - > set_shape ( shape ) ;
2017-03-05 16:44:50 +01:00
StaticBody * body = memnew ( StaticBody ) ;
2016-05-23 22:10:26 +02:00
body - > add_child ( cshape ) ;
2022-10-20 09:06:17 +02:00
Node * owner = get_tree ( ) - > get_edited_scene_root ( ) ;
2016-05-23 22:10:26 +02:00
2017-03-05 16:44:50 +01:00
ur - > add_do_method ( instance , " add_child " , body ) ;
ur - > add_do_method ( body , " set_owner " , owner ) ;
ur - > add_do_method ( cshape , " set_owner " , owner ) ;
2016-05-23 22:10:26 +02:00
ur - > add_do_reference ( body ) ;
2017-03-05 16:44:50 +01:00
ur - > add_undo_method ( instance , " remove_child " , body ) ;
2016-05-23 22:10:26 +02:00
}
ur - > commit_action ( ) ;
} break ;
2019-04-10 22:46:04 +02:00
case MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE : {
2017-03-05 16:44:50 +01:00
if ( node = = get_tree ( ) - > get_edited_scene_root ( ) ) {
2016-05-23 22:10:26 +02:00
err_dialog - > set_text ( TTR ( " This doesn't work on scene root! " ) ) ;
err_dialog - > popup_centered_minsize ( ) ;
return ;
}
2019-04-10 22:46:04 +02:00
Ref < Shape > shape = mesh - > create_trimesh_shape ( ) ;
2021-05-05 12:44:11 +02:00
if ( shape . is_null ( ) ) {
2016-05-23 22:10:26 +02:00
return ;
2021-05-05 12:44:11 +02:00
}
2016-05-23 22:10:26 +02:00
2017-03-05 16:44:50 +01:00
CollisionShape * cshape = memnew ( CollisionShape ) ;
2016-05-23 22:10:26 +02:00
cshape - > set_shape ( shape ) ;
2020-09-14 00:42:52 +02:00
cshape - > set_transform ( node - > get_transform ( ) ) ;
2016-05-23 22:10:26 +02:00
2022-10-20 09:06:17 +02:00
Node * owner = get_tree ( ) - > get_edited_scene_root ( ) ;
2016-05-23 22:10:26 +02:00
UndoRedo * ur = EditorNode : : get_singleton ( ) - > get_undo_redo ( ) ;
2019-04-10 22:46:04 +02:00
ur - > create_action ( TTR ( " Create Trimesh Static Shape " ) ) ;
2016-05-23 22:10:26 +02:00
2017-03-05 16:44:50 +01:00
ur - > add_do_method ( node - > get_parent ( ) , " add_child " , cshape ) ;
ur - > add_do_method ( node - > get_parent ( ) , " move_child " , cshape , node - > get_index ( ) + 1 ) ;
ur - > add_do_method ( cshape , " set_owner " , owner ) ;
2016-05-23 22:10:26 +02:00
ur - > add_do_reference ( cshape ) ;
2017-03-05 16:44:50 +01:00
ur - > add_undo_method ( node - > get_parent ( ) , " remove_child " , cshape ) ;
2016-05-23 22:10:26 +02:00
ur - > commit_action ( ) ;
2019-04-10 22:46:04 +02:00
} break ;
2021-07-10 00:31:05 +02:00
case MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE :
case MENU_OPTION_CREATE_SIMPLIFIED_CONVEX_COLLISION_SHAPE : {
2019-04-10 22:46:04 +02:00
if ( node = = get_tree ( ) - > get_edited_scene_root ( ) ) {
2020-01-31 16:30:27 +01:00
err_dialog - > set_text ( TTR ( " Can't create a single convex collision shape for the scene root. " ) ) ;
err_dialog - > popup_centered_minsize ( ) ;
return ;
}
2021-07-10 00:31:05 +02:00
bool simplify = ( p_option = = MENU_OPTION_CREATE_SIMPLIFIED_CONVEX_COLLISION_SHAPE ) ;
Ref < Shape > shape = mesh - > create_convex_shape ( true , simplify ) ;
2020-01-31 16:30:27 +01:00
if ( shape . is_null ( ) ) {
err_dialog - > set_text ( TTR ( " Couldn't create a single convex collision shape. " ) ) ;
err_dialog - > popup_centered_minsize ( ) ;
return ;
}
UndoRedo * ur = EditorNode : : get_singleton ( ) - > get_undo_redo ( ) ;
2021-07-10 00:31:05 +02:00
if ( simplify ) {
ur - > create_action ( TTR ( " Create Simplified Convex Shape " ) ) ;
} else {
ur - > create_action ( TTR ( " Create Single Convex Shape " ) ) ;
}
2020-01-31 16:30:27 +01:00
CollisionShape * cshape = memnew ( CollisionShape ) ;
cshape - > set_shape ( shape ) ;
cshape - > set_transform ( node - > get_transform ( ) ) ;
2022-10-20 09:06:17 +02:00
Node * owner = get_tree ( ) - > get_edited_scene_root ( ) ;
2020-01-31 16:30:27 +01:00
ur - > add_do_method ( node - > get_parent ( ) , " add_child " , cshape ) ;
ur - > add_do_method ( node - > get_parent ( ) , " move_child " , cshape , node - > get_index ( ) + 1 ) ;
ur - > add_do_method ( cshape , " set_owner " , owner ) ;
ur - > add_do_reference ( cshape ) ;
ur - > add_undo_method ( node - > get_parent ( ) , " remove_child " , cshape ) ;
ur - > commit_action ( ) ;
} break ;
2021-07-10 00:31:05 +02:00
2020-01-31 16:30:27 +01:00
case MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES : {
if ( node = = get_tree ( ) - > get_edited_scene_root ( ) ) {
err_dialog - > set_text ( TTR ( " Can't create multiple convex collision shapes for the scene root. " ) ) ;
2019-04-10 22:46:04 +02:00
err_dialog - > popup_centered_minsize ( ) ;
return ;
}
2021-05-04 14:20:36 +02:00
Vector < Ref < Shape > > shapes = mesh - > convex_decompose ( ) ;
2019-04-10 22:46:04 +02:00
if ( ! shapes . size ( ) ) {
2020-01-31 16:30:27 +01:00
err_dialog - > set_text ( TTR ( " Couldn't create any collision shapes. " ) ) ;
2019-04-10 22:46:04 +02:00
err_dialog - > popup_centered_minsize ( ) ;
return ;
}
UndoRedo * ur = EditorNode : : get_singleton ( ) - > get_undo_redo ( ) ;
2020-01-31 16:30:27 +01:00
ur - > create_action ( TTR ( " Create Multiple Convex Shapes " ) ) ;
2019-04-10 22:46:04 +02:00
for ( int i = 0 ; i < shapes . size ( ) ; i + + ) {
CollisionShape * cshape = memnew ( CollisionShape ) ;
cshape - > set_shape ( shapes [ i ] ) ;
2019-11-02 15:08:50 +01:00
cshape - > set_transform ( node - > get_transform ( ) ) ;
2019-04-10 22:46:04 +02:00
2022-10-20 09:06:17 +02:00
Node * owner = get_tree ( ) - > get_edited_scene_root ( ) ;
2019-04-10 22:46:04 +02:00
ur - > add_do_method ( node - > get_parent ( ) , " add_child " , cshape ) ;
ur - > add_do_method ( node - > get_parent ( ) , " move_child " , cshape , node - > get_index ( ) + 1 ) ;
ur - > add_do_method ( cshape , " set_owner " , owner ) ;
ur - > add_do_reference ( cshape ) ;
ur - > add_undo_method ( node - > get_parent ( ) , " remove_child " , cshape ) ;
}
ur - > commit_action ( ) ;
2016-05-23 22:10:26 +02:00
} break ;
case MENU_OPTION_CREATE_NAVMESH : {
2017-03-05 16:44:50 +01:00
Ref < NavigationMesh > nmesh = memnew ( NavigationMesh ) ;
2016-05-23 22:10:26 +02:00
2021-05-05 12:44:11 +02:00
if ( nmesh . is_null ( ) ) {
2016-05-23 22:10:26 +02:00
return ;
2021-05-05 12:44:11 +02:00
}
2016-05-23 22:10:26 +02:00
nmesh - > create_from_mesh ( mesh ) ;
2017-03-05 16:44:50 +01:00
NavigationMeshInstance * nmi = memnew ( NavigationMeshInstance ) ;
2016-05-23 22:10:26 +02:00
nmi - > set_navigation_mesh ( nmesh ) ;
2022-10-20 09:06:17 +02:00
Node * owner = get_tree ( ) - > get_edited_scene_root ( ) ;
2016-05-23 22:10:26 +02:00
UndoRedo * ur = EditorNode : : get_singleton ( ) - > get_undo_redo ( ) ;
ur - > create_action ( TTR ( " Create Navigation Mesh " ) ) ;
2017-03-05 16:44:50 +01:00
ur - > add_do_method ( node , " add_child " , nmi ) ;
ur - > add_do_method ( nmi , " set_owner " , owner ) ;
2016-05-23 22:10:26 +02:00
ur - > add_do_reference ( nmi ) ;
2017-03-05 16:44:50 +01:00
ur - > add_undo_method ( node , " remove_child " , nmi ) ;
2016-05-23 22:10:26 +02:00
ur - > commit_action ( ) ;
} break ;
case MENU_OPTION_CREATE_OUTLINE_MESH : {
outline_dialog - > popup_centered ( Vector2 ( 200 , 90 ) ) ;
} break ;
2017-12-09 18:11:26 +01:00
case MENU_OPTION_CREATE_UV2 : {
2019-02-12 21:10:08 +01:00
Ref < ArrayMesh > mesh2 = node - > get_mesh ( ) ;
if ( ! mesh2 . is_valid ( ) ) {
2017-12-09 18:11:26 +01:00
err_dialog - > set_text ( TTR ( " Contained Mesh is not of type ArrayMesh. " ) ) ;
err_dialog - > popup_centered_minsize ( ) ;
return ;
}
2019-02-12 21:10:08 +01:00
Error err = mesh2 - > lightmap_unwrap ( node - > get_global_transform ( ) ) ;
2017-12-09 18:11:26 +01:00
if ( err ! = OK ) {
err_dialog - > set_text ( TTR ( " UV Unwrap failed, mesh may not be manifold? " ) ) ;
err_dialog - > popup_centered_minsize ( ) ;
return ;
}
} break ;
case MENU_OPTION_DEBUG_UV1 : {
2019-02-12 21:10:08 +01:00
Ref < Mesh > mesh2 = node - > get_mesh ( ) ;
if ( ! mesh2 . is_valid ( ) ) {
2017-12-09 18:11:26 +01:00
err_dialog - > set_text ( TTR ( " No mesh to debug. " ) ) ;
err_dialog - > popup_centered_minsize ( ) ;
return ;
}
_create_uv_lines ( 0 ) ;
} break ;
case MENU_OPTION_DEBUG_UV2 : {
2019-02-12 21:10:08 +01:00
Ref < Mesh > mesh2 = node - > get_mesh ( ) ;
if ( ! mesh2 . is_valid ( ) ) {
2017-12-09 18:11:26 +01:00
err_dialog - > set_text ( TTR ( " No mesh to debug. " ) ) ;
err_dialog - > popup_centered_minsize ( ) ;
return ;
}
_create_uv_lines ( 1 ) ;
} break ;
}
}
struct MeshInstanceEditorEdgeSort {
Vector2 a ;
Vector2 b ;
bool operator < ( const MeshInstanceEditorEdgeSort & p_b ) const {
2021-05-05 12:44:11 +02:00
if ( a = = p_b . a ) {
2017-12-09 18:11:26 +01:00
return b < p_b . b ;
2021-05-05 12:44:11 +02:00
} else {
2017-12-09 18:11:26 +01:00
return a < p_b . a ;
2021-05-05 12:44:11 +02:00
}
2017-12-09 18:11:26 +01:00
}
MeshInstanceEditorEdgeSort ( ) { }
MeshInstanceEditorEdgeSort ( const Vector2 & p_a , const Vector2 & p_b ) {
if ( p_a < p_b ) {
a = p_a ;
b = p_b ;
} else {
b = p_a ;
a = p_b ;
}
}
} ;
void MeshInstanceEditor : : _create_uv_lines ( int p_layer ) {
Ref < Mesh > mesh = node - > get_mesh ( ) ;
ERR_FAIL_COND ( ! mesh . is_valid ( ) ) ;
Set < MeshInstanceEditorEdgeSort > edges ;
uv_lines . clear ( ) ;
for ( int i = 0 ; i < mesh - > get_surface_count ( ) ; i + + ) {
2021-05-05 12:44:11 +02:00
if ( mesh - > surface_get_primitive_type ( i ) ! = Mesh : : PRIMITIVE_TRIANGLES ) {
2017-12-09 18:11:26 +01:00
continue ;
2021-05-05 12:44:11 +02:00
}
2017-12-09 18:11:26 +01:00
Array a = mesh - > surface_get_arrays ( i ) ;
PoolVector < Vector2 > uv = a [ p_layer = = 0 ? Mesh : : ARRAY_TEX_UV : Mesh : : ARRAY_TEX_UV2 ] ;
if ( uv . size ( ) = = 0 ) {
2021-07-25 01:11:24 +02:00
err_dialog - > set_text ( vformat ( TTR ( " Mesh has no UV in layer %d. " ) , p_layer + 1 ) ) ;
2017-12-09 18:11:26 +01:00
err_dialog - > popup_centered_minsize ( ) ;
return ;
}
PoolVector < Vector2 > : : Read r = uv . read ( ) ;
PoolVector < int > indices = a [ Mesh : : ARRAY_INDEX ] ;
PoolVector < int > : : Read ri ;
int ic ;
bool use_indices ;
if ( indices . size ( ) ) {
ic = indices . size ( ) ;
ri = indices . read ( ) ;
use_indices = true ;
} else {
ic = uv . size ( ) ;
use_indices = false ;
}
for ( int j = 0 ; j < ic ; j + = 3 ) {
for ( int k = 0 ; k < 3 ; k + + ) {
MeshInstanceEditorEdgeSort edge ;
if ( use_indices ) {
edge . a = r [ ri [ j + k ] ] ;
edge . b = r [ ri [ j + ( ( k + 1 ) % 3 ) ] ] ;
} else {
edge . a = r [ j + k ] ;
edge . b = r [ j + ( ( k + 1 ) % 3 ) ] ;
}
2021-05-05 12:44:11 +02:00
if ( edges . has ( edge ) ) {
2017-12-09 18:11:26 +01:00
continue ;
2021-05-05 12:44:11 +02:00
}
2017-12-09 18:11:26 +01:00
uv_lines . push_back ( edge . a ) ;
uv_lines . push_back ( edge . b ) ;
edges . insert ( edge ) ;
}
}
2016-05-23 22:10:26 +02:00
}
2017-12-09 18:11:26 +01:00
debug_uv_dialog - > popup_centered_minsize ( ) ;
}
void MeshInstanceEditor : : _debug_uv_draw ( ) {
2021-05-05 12:44:11 +02:00
if ( uv_lines . size ( ) = = 0 ) {
2017-12-09 18:11:26 +01:00
return ;
2021-05-05 12:44:11 +02:00
}
2017-12-09 18:11:26 +01:00
debug_uv - > set_clip_contents ( true ) ;
2021-07-25 01:11:24 +02:00
debug_uv - > draw_rect ( Rect2 ( Vector2 ( ) , debug_uv - > get_size ( ) ) , get_color ( " dark_color_3 " , " Editor " ) ) ;
2017-12-09 18:11:26 +01:00
debug_uv - > draw_set_transform ( Vector2 ( ) , 0 , debug_uv - > get_size ( ) ) ;
2021-07-25 01:11:24 +02:00
// Use a translucent color to allow overlapping triangles to be visible.
debug_uv - > draw_multiline ( uv_lines , get_color ( " mono_color " , " Editor " ) * Color ( 1 , 1 , 1 , 0.5 ) , Math : : round ( EDSCALE ) ) ;
2016-05-23 22:10:26 +02:00
}
void MeshInstanceEditor : : _create_outline_mesh ( ) {
Ref < Mesh > mesh = node - > get_mesh ( ) ;
if ( mesh . is_null ( ) ) {
err_dialog - > set_text ( TTR ( " MeshInstance lacks a Mesh! " ) ) ;
err_dialog - > popup_centered_minsize ( ) ;
return ;
}
2016-06-21 00:57:21 +02:00
if ( mesh - > get_surface_count ( ) = = 0 ) {
err_dialog - > set_text ( TTR ( " Mesh has not surface to create outlines from! " ) ) ;
err_dialog - > popup_centered_minsize ( ) ;
2018-04-01 17:06:47 +02:00
return ;
} else if ( mesh - > get_surface_count ( ) = = 1 & & mesh - > surface_get_primitive_type ( 0 ) ! = Mesh : : PRIMITIVE_TRIANGLES ) {
err_dialog - > set_text ( TTR ( " Mesh primitive type is not PRIMITIVE_TRIANGLES! " ) ) ;
err_dialog - > popup_centered_minsize ( ) ;
2016-06-21 00:57:21 +02:00
return ;
}
2017-01-04 05:16:14 +01:00
Ref < Mesh > mesho = mesh - > create_outline ( outline_size - > get_value ( ) ) ;
2016-05-23 22:10:26 +02:00
if ( mesho . is_null ( ) ) {
err_dialog - > set_text ( TTR ( " Could not create outline! " ) ) ;
err_dialog - > popup_centered_minsize ( ) ;
return ;
}
2017-03-05 16:44:50 +01:00
MeshInstance * mi = memnew ( MeshInstance ) ;
2016-05-23 22:10:26 +02:00
mi - > set_mesh ( mesho ) ;
2022-10-20 09:06:17 +02:00
Node * owner = get_tree ( ) - > get_edited_scene_root ( ) ;
2016-05-23 22:10:26 +02:00
UndoRedo * ur = EditorNode : : get_singleton ( ) - > get_undo_redo ( ) ;
ur - > create_action ( TTR ( " Create Outline " ) ) ;
2017-03-05 16:44:50 +01:00
ur - > add_do_method ( node , " add_child " , mi ) ;
ur - > add_do_method ( mi , " set_owner " , owner ) ;
2016-05-23 22:10:26 +02:00
ur - > add_do_reference ( mi ) ;
2017-03-05 16:44:50 +01:00
ur - > add_undo_method ( node , " remove_child " , mi ) ;
2016-05-23 22:10:26 +02:00
ur - > commit_action ( ) ;
}
void MeshInstanceEditor : : _bind_methods ( ) {
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( " _menu_option " , & MeshInstanceEditor : : _menu_option ) ;
ClassDB : : bind_method ( " _create_outline_mesh " , & MeshInstanceEditor : : _create_outline_mesh ) ;
2017-12-09 18:11:26 +01:00
ClassDB : : bind_method ( " _debug_uv_draw " , & MeshInstanceEditor : : _debug_uv_draw ) ;
2016-05-23 22:10:26 +02:00
}
MeshInstanceEditor : : MeshInstanceEditor ( ) {
2017-03-05 16:44:50 +01:00
options = memnew ( MenuButton ) ;
2019-04-25 15:27:33 +02:00
options - > set_switch_on_hover ( true ) ;
2016-05-23 22:10:26 +02:00
SpatialEditor : : get_singleton ( ) - > add_control_to_menu_panel ( options ) ;
2016-06-01 13:32:20 +02:00
options - > set_text ( TTR ( " Mesh " ) ) ;
2017-03-05 16:44:50 +01:00
options - > set_icon ( EditorNode : : get_singleton ( ) - > get_gui_base ( ) - > get_icon ( " MeshInstance " , " EditorIcons " ) ) ;
2016-05-23 22:10:26 +02:00
2017-03-05 16:44:50 +01:00
options - > get_popup ( ) - > add_item ( TTR ( " Create Trimesh Static Body " ) , MENU_OPTION_CREATE_STATIC_TRIMESH_BODY ) ;
2020-01-31 16:30:27 +01:00
options - > get_popup ( ) - > set_item_tooltip ( options - > get_popup ( ) - > get_item_count ( ) - 1 , TTR ( " Creates a StaticBody and assigns a polygon-based collision shape to it automatically. \n This is the most accurate (but slowest) option for collision detection. " ) ) ;
2016-05-23 22:10:26 +02:00
options - > get_popup ( ) - > add_separator ( ) ;
2017-03-05 16:44:50 +01:00
options - > get_popup ( ) - > add_item ( TTR ( " Create Trimesh Collision Sibling " ) , MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE ) ;
2020-01-31 16:30:27 +01:00
options - > get_popup ( ) - > set_item_tooltip ( options - > get_popup ( ) - > get_item_count ( ) - 1 , TTR ( " Creates a polygon-based collision shape. \n This is the most accurate (but slowest) option for collision detection. " ) ) ;
2020-02-26 22:25:55 +01:00
options - > get_popup ( ) - > add_item ( TTR ( " Create Single Convex Collision Sibling " ) , MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE ) ;
2020-01-31 16:30:27 +01:00
options - > get_popup ( ) - > set_item_tooltip ( options - > get_popup ( ) - > get_item_count ( ) - 1 , TTR ( " Creates a single convex collision shape. \n This is the fastest (but least accurate) option for collision detection. " ) ) ;
2021-07-10 00:31:05 +02:00
options - > get_popup ( ) - > add_item ( TTR ( " Create Simplified Convex Collision Sibling " ) , MENU_OPTION_CREATE_SIMPLIFIED_CONVEX_COLLISION_SHAPE ) ;
options - > get_popup ( ) - > set_item_tooltip ( options - > get_popup ( ) - > get_item_count ( ) - 1 , TTR ( " Creates a simplified convex collision shape. \n This is similar to single collision shape, but can result in a simpler geometry in some cases, at the cost of accuracy. " ) ) ;
2020-01-31 16:30:27 +01:00
options - > get_popup ( ) - > add_item ( TTR ( " Create Multiple Convex Collision Siblings " ) , MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES ) ;
2021-07-10 00:31:05 +02:00
options - > get_popup ( ) - > set_item_tooltip ( options - > get_popup ( ) - > get_item_count ( ) - 1 , TTR ( " Creates a polygon-based collision shape. \n This is a performance middle-ground between a single convex collision and a polygon-based collision. " ) ) ;
2016-05-23 22:10:26 +02:00
options - > get_popup ( ) - > add_separator ( ) ;
2017-03-05 16:44:50 +01:00
options - > get_popup ( ) - > add_item ( TTR ( " Create Navigation Mesh " ) , MENU_OPTION_CREATE_NAVMESH ) ;
2016-05-23 22:10:26 +02:00
options - > get_popup ( ) - > add_separator ( ) ;
2018-04-22 19:36:01 +02:00
options - > get_popup ( ) - > add_item ( TTR ( " Create Outline Mesh... " ) , MENU_OPTION_CREATE_OUTLINE_MESH ) ;
2024-02-08 20:10:26 +01:00
options - > get_popup ( ) - > set_item_tooltip ( options - > get_popup ( ) - > get_item_count ( ) - 1 , TTR ( " Creates a static outline mesh. The outline mesh will have its normals flipped automatically. \n This can be used instead of the Material3D Grow property when using that property isn't possible. " ) ) ;
2017-12-09 18:11:26 +01:00
options - > get_popup ( ) - > add_separator ( ) ;
options - > get_popup ( ) - > add_item ( TTR ( " View UV1 " ) , MENU_OPTION_DEBUG_UV1 ) ;
options - > get_popup ( ) - > add_item ( TTR ( " View UV2 " ) , MENU_OPTION_DEBUG_UV2 ) ;
options - > get_popup ( ) - > add_item ( TTR ( " Unwrap UV2 for Lightmap/AO " ) , MENU_OPTION_CREATE_UV2 ) ;
2016-05-23 22:10:26 +02:00
2017-03-05 16:44:50 +01:00
options - > get_popup ( ) - > connect ( " id_pressed " , this , " _menu_option " ) ;
2016-05-23 22:10:26 +02:00
2017-03-05 16:44:50 +01:00
outline_dialog = memnew ( ConfirmationDialog ) ;
2016-05-23 22:10:26 +02:00
outline_dialog - > set_title ( TTR ( " Create Outline Mesh " ) ) ;
outline_dialog - > get_ok ( ) - > set_text ( TTR ( " Create " ) ) ;
2017-03-05 16:44:50 +01:00
VBoxContainer * outline_dialog_vbc = memnew ( VBoxContainer ) ;
2016-05-23 22:10:26 +02:00
outline_dialog - > add_child ( outline_dialog_vbc ) ;
2017-01-10 05:49:55 +01:00
//outline_dialog->set_child_rect(outline_dialog_vbc);
2016-05-23 22:10:26 +02:00
2017-03-05 16:44:50 +01:00
outline_size = memnew ( SpinBox ) ;
2016-05-23 22:10:26 +02:00
outline_size - > set_min ( 0.001 ) ;
outline_size - > set_max ( 1024 ) ;
outline_size - > set_step ( 0.001 ) ;
2017-01-04 05:16:14 +01:00
outline_size - > set_value ( 0.05 ) ;
2017-03-05 16:44:50 +01:00
outline_dialog_vbc - > add_margin_child ( TTR ( " Outline Size: " ) , outline_size ) ;
2016-05-23 22:10:26 +02:00
add_child ( outline_dialog ) ;
2017-03-05 16:44:50 +01:00
outline_dialog - > connect ( " confirmed " , this , " _create_outline_mesh " ) ;
2016-05-23 22:10:26 +02:00
2017-03-05 16:44:50 +01:00
err_dialog = memnew ( AcceptDialog ) ;
2016-05-23 22:10:26 +02:00
add_child ( err_dialog ) ;
2017-12-09 18:11:26 +01:00
debug_uv_dialog = memnew ( AcceptDialog ) ;
2019-12-27 03:31:55 +01:00
debug_uv_dialog - > set_title ( TTR ( " UV Channel Debug " ) ) ;
2017-12-09 18:11:26 +01:00
add_child ( debug_uv_dialog ) ;
debug_uv = memnew ( Control ) ;
debug_uv - > set_custom_minimum_size ( Size2 ( 600 , 600 ) * EDSCALE ) ;
debug_uv - > connect ( " draw " , this , " _debug_uv_draw " ) ;
debug_uv_dialog - > add_child ( debug_uv ) ;
2016-05-23 22:10:26 +02:00
}
void MeshInstanceEditorPlugin : : edit ( Object * p_object ) {
2017-08-24 22:58:51 +02:00
mesh_editor - > edit ( Object : : cast_to < MeshInstance > ( p_object ) ) ;
2016-05-23 22:10:26 +02:00
}
bool MeshInstanceEditorPlugin : : handles ( Object * p_object ) const {
2017-01-03 03:03:46 +01:00
return p_object - > is_class ( " MeshInstance " ) ;
2016-05-23 22:10:26 +02:00
}
void MeshInstanceEditorPlugin : : make_visible ( bool p_visible ) {
if ( p_visible ) {
mesh_editor - > options - > show ( ) ;
} else {
mesh_editor - > options - > hide ( ) ;
2021-05-04 16:00:45 +02:00
mesh_editor - > edit ( nullptr ) ;
2016-05-23 22:10:26 +02:00
}
}
MeshInstanceEditorPlugin : : MeshInstanceEditorPlugin ( EditorNode * p_node ) {
2017-03-05 16:44:50 +01:00
editor = p_node ;
mesh_editor = memnew ( MeshInstanceEditor ) ;
2016-05-23 22:10:26 +02:00
editor - > get_viewport ( ) - > add_child ( mesh_editor ) ;
mesh_editor - > options - > hide ( ) ;
}
2017-03-05 16:44:50 +01:00
MeshInstanceEditorPlugin : : ~ MeshInstanceEditorPlugin ( ) {
2016-05-23 22:10:26 +02:00
}