30
30
31
31
#include " collision_polygon_3d_gizmo_plugin.h"
32
32
33
+ #include " core/math/geometry_2d.h"
33
34
#include " scene/3d/physics/collision_polygon_3d.h"
34
35
35
36
CollisionPolygon3DGizmoPlugin::CollisionPolygon3DGizmoPlugin () {
36
- const Color gizmo_color = SceneTree::get_singleton ()->get_debug_collisions_color ();
37
- create_material (" shape_material" , gizmo_color);
38
- const float gizmo_value = gizmo_color.get_v ();
39
- const Color gizmo_color_disabled = Color (gizmo_value, gizmo_value, gizmo_value, 0.65 );
40
- create_material (" shape_material_disabled" , gizmo_color_disabled);
37
+ create_collision_material (" shape_material" , 2.0 );
38
+ create_collision_material (" shape_material_arraymesh" , 0.0625 );
39
+
40
+ create_collision_material (" shape_material_disabled" , 0.0625 );
41
+ create_collision_material (" shape_material_arraymesh_disabled" , 0.015625 );
42
+ }
43
+
44
+ void CollisionPolygon3DGizmoPlugin::create_collision_material (const String &p_name, float p_alpha) {
45
+ Vector<Ref<StandardMaterial3D>> mats;
46
+
47
+ const Color collision_color (1.0 , 1.0 , 1.0 , p_alpha);
48
+
49
+ for (int i = 0 ; i < 4 ; i++) {
50
+ bool instantiated = i < 2 ;
51
+
52
+ Ref<StandardMaterial3D> material;
53
+ material.instantiate ();
54
+
55
+ Color color = collision_color;
56
+ color.a *= instantiated ? 0.25 : 1.0 ;
57
+
58
+ material->set_albedo (color);
59
+ material->set_shading_mode (StandardMaterial3D::SHADING_MODE_UNSHADED);
60
+ material->set_transparency (StandardMaterial3D::TRANSPARENCY_ALPHA);
61
+ material->set_render_priority (StandardMaterial3D::RENDER_PRIORITY_MIN + 1 );
62
+ material->set_cull_mode (StandardMaterial3D::CULL_BACK);
63
+ material->set_flag (StandardMaterial3D::FLAG_DISABLE_FOG, true );
64
+ material->set_flag (StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true );
65
+ material->set_flag (StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true );
66
+
67
+ mats.push_back (material);
68
+ }
69
+
70
+ materials[p_name] = mats;
41
71
}
42
72
43
73
bool CollisionPolygon3DGizmoPlugin::has_gizmo (Node3D *p_spatial) {
@@ -57,6 +87,13 @@ void CollisionPolygon3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
57
87
58
88
p_gizmo->clear ();
59
89
90
+ const Ref<StandardMaterial3D> material =
91
+ get_material (!polygon->is_disabled () ? " shape_material" : " shape_material_disabled" , p_gizmo);
92
+ const Ref<StandardMaterial3D> material_arraymesh =
93
+ get_material (!polygon->is_disabled () ? " shape_material_arraymesh" : " shape_material_arraymesh_disabled" , p_gizmo);
94
+
95
+ const Color collision_color = polygon->is_disabled () ? Color (1.0 , 1.0 , 1.0 , 0.75 ) : polygon->get_debug_color ();
96
+
60
97
Vector<Vector2> points = polygon->get_polygon ();
61
98
float depth = polygon->get_depth () * 0.5 ;
62
99
@@ -71,9 +108,125 @@ void CollisionPolygon3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
71
108
lines.push_back (Vector3 (points[i].x , points[i].y , -depth));
72
109
}
73
110
74
- const Ref<Material> material =
75
- get_material (!polygon->is_disabled () ? " shape_material" : " shape_material_disabled" , p_gizmo);
111
+ if (polygon->get_debug_fill_enabled ()) {
112
+ Ref<ArrayMesh> array_mesh;
113
+ array_mesh.instantiate ();
114
+
115
+ Vector<Vector3> verts;
116
+ Vector<Color> colors;
117
+ Vector<int > indices;
118
+
119
+ // Determine orientation of the 2D polygon's vertices to determine
120
+ // which direction to draw outer polygons.
121
+ float signed_area = 0 .0f ;
122
+ for (int i = 0 ; i < points.size (); i++) {
123
+ const int j = (i + 1 ) % points.size ();
124
+ signed_area += points[i].x * points[j].y - points[j].x * points[i].y ;
125
+ }
126
+
127
+ // Generate triangles for the sides of the extruded polygon.
128
+ for (int i = 0 ; i < points.size (); i++) {
129
+ verts.push_back (Vector3 (points[i].x , points[i].y , depth));
130
+ verts.push_back (Vector3 (points[i].x , points[i].y , -depth));
131
+
132
+ colors.push_back (collision_color);
133
+ colors.push_back (collision_color);
134
+ }
135
+
136
+ for (int i = 0 ; i < verts.size (); i += 2 ) {
137
+ const int j = (i + 1 ) % verts.size ();
138
+ const int k = (i + 2 ) % verts.size ();
139
+ const int l = (i + 3 ) % verts.size ();
140
+
141
+ indices.push_back (i);
142
+ if (signed_area < 0 ) {
143
+ indices.push_back (j);
144
+ indices.push_back (k);
145
+ } else {
146
+ indices.push_back (k);
147
+ indices.push_back (j);
148
+ }
149
+
150
+ indices.push_back (j);
151
+ if (signed_area < 0 ) {
152
+ indices.push_back (l);
153
+ indices.push_back (k);
154
+ } else {
155
+ indices.push_back (k);
156
+ indices.push_back (l);
157
+ }
158
+ }
159
+
160
+ Vector<Vector<Vector2>> decomp = Geometry2D::decompose_polygon_in_convex (polygon->get_polygon ());
161
+
162
+ // Generate triangles for the bottom cap of the extruded polygon.
163
+ for (int i = 0 ; i < decomp.size (); i++) {
164
+ Vector<Vector3> cap_verts_bottom;
165
+ Vector<Color> cap_colours_bottom;
166
+ Vector<int > cap_indices_bottom;
167
+
168
+ const int index_offset = verts.size ();
169
+
170
+ const Vector<Vector2> &convex = decomp[i];
171
+
172
+ for (int j = 0 ; j < convex.size (); j++) {
173
+ cap_verts_bottom.push_back (Vector3 (convex[j].x , convex[j].y , -depth));
174
+ cap_colours_bottom.push_back (collision_color);
175
+ }
176
+
177
+ if (convex.size () >= 3 ) {
178
+ for (int j = 1 ; j < convex.size (); j++) {
179
+ const int k = (j + 1 ) % convex.size ();
180
+
181
+ cap_indices_bottom.push_back (index_offset + 0 );
182
+ cap_indices_bottom.push_back (index_offset + j);
183
+ cap_indices_bottom.push_back (index_offset + k);
184
+ }
185
+ }
186
+ verts.append_array (cap_verts_bottom);
187
+ colors.append_array (cap_colours_bottom);
188
+ indices.append_array (cap_indices_bottom);
189
+ }
190
+
191
+ // Generate triangles for the top cap of the extruded polygon.
192
+ for (int i = 0 ; i < decomp.size (); i++) {
193
+ Vector<Vector3> cap_verts_top;
194
+ Vector<Color> cap_colours_top;
195
+ Vector<int > cap_indices_top;
196
+
197
+ const int index_offset = verts.size ();
198
+
199
+ const Vector<Vector2> &convex = decomp[i];
200
+
201
+ for (int j = 0 ; j < convex.size (); j++) {
202
+ cap_verts_top.push_back (Vector3 (convex[j].x , convex[j].y , depth));
203
+ cap_colours_top.push_back (collision_color);
204
+ }
205
+
206
+ if (convex.size () >= 3 ) {
207
+ for (int j = 1 ; j < convex.size (); j++) {
208
+ const int k = (j + 1 ) % convex.size ();
209
+
210
+ cap_indices_top.push_back (index_offset + k);
211
+ cap_indices_top.push_back (index_offset + j);
212
+ cap_indices_top.push_back (index_offset + 0 );
213
+ }
214
+ }
215
+ verts.append_array (cap_verts_top);
216
+ colors.append_array (cap_colours_top);
217
+ indices.append_array (cap_indices_top);
218
+ }
219
+
220
+ Array a;
221
+ a.resize (Mesh::ARRAY_MAX);
222
+ a[RS::ARRAY_VERTEX] = verts;
223
+ a[RS::ARRAY_COLOR] = colors;
224
+ a[RS::ARRAY_INDEX] = indices;
225
+ array_mesh->add_surface_from_arrays (Mesh::PRIMITIVE_TRIANGLES, a);
226
+
227
+ p_gizmo->add_mesh (array_mesh, material_arraymesh);
228
+ }
76
229
77
- p_gizmo->add_lines (lines, material);
230
+ p_gizmo->add_lines (lines, material, false , collision_color );
78
231
p_gizmo->add_collision_segments (lines);
79
232
}
0 commit comments