@@ -58,7 +58,6 @@ class EditorSceneImporter : public RefCounted {
58
58
IMPORT_FAIL_ON_MISSING_DEPENDENCIES = 4 ,
59
59
IMPORT_GENERATE_TANGENT_ARRAYS = 8 ,
60
60
IMPORT_USE_NAMED_SKIN_BINDS = 16 ,
61
-
62
61
};
63
62
64
63
virtual uint32_t get_import_flags () const ;
@@ -118,9 +117,25 @@ class ResourceImporterScene : public ResourceImporter {
118
117
MESH_OVERRIDE_DISABLE,
119
118
};
120
119
120
+ enum BodyType {
121
+ BODY_TYPE_STATIC,
122
+ BODY_TYPE_DYNAMIC,
123
+ BODY_TYPE_AREA
124
+ };
125
+
126
+ enum ShapeType {
127
+ SHAPE_TYPE_DECOMPOSE_CONVEX,
128
+ SHAPE_TYPE_SIMPLE_CONVEX,
129
+ SHAPE_TYPE_TRIMESH,
130
+ SHAPE_TYPE_BOX,
131
+ SHAPE_TYPE_SPHERE,
132
+ SHAPE_TYPE_CYLINDER,
133
+ SHAPE_TYPE_CAPSULE,
134
+ };
135
+
121
136
void _replace_owner (Node *p_node, Node *p_scene, Node *p_new_owner);
122
137
void _generate_meshes (Node *p_node, const Dictionary &p_mesh_data, bool p_generate_lods, bool p_create_shadow_meshes, LightBakeMode p_light_bake_mode, float p_lightmap_texel_size, const Vector<uint8_t > &p_src_lightmap_cache, Vector<Vector<uint8_t >> &r_lightmap_caches);
123
- void _add_shapes (Node *p_node, const List <Ref<Shape3D>> &p_shapes);
138
+ void _add_shapes (Node *p_node, const Vector <Ref<Shape3D>> &p_shapes);
124
139
125
140
public:
126
141
static ResourceImporterScene *get_singleton () { return singleton; }
@@ -152,14 +167,15 @@ class ResourceImporterScene : public ResourceImporter {
152
167
153
168
void get_internal_import_options (InternalImportCategory p_category, List<ImportOption> *r_options) const ;
154
169
bool get_internal_option_visibility (InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const ;
170
+ bool get_internal_option_update_view (InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const ;
155
171
156
172
virtual void get_import_options (List<ImportOption> *r_options, int p_preset = 0 ) const override ;
157
173
virtual bool get_option_visibility (const String &p_option, const Map<StringName, Variant> &p_options) const override ;
158
174
// Import scenes *after* everything else (such as textures).
159
175
virtual int get_import_order () const override { return ResourceImporter::IMPORT_ORDER_SCENE; }
160
176
161
- Node *_pre_fix_node (Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, List <Ref<Shape3D>>> &collision_map);
162
- Node *_post_fix_node (Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, List <Ref<Shape3D>>> &collision_map, Set<Ref<EditorSceneImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps);
177
+ Node *_pre_fix_node (Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, Vector <Ref<Shape3D>>> &collision_map);
178
+ Node *_post_fix_node (Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, Vector <Ref<Shape3D>>> &collision_map, Set<Ref<EditorSceneImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps);
163
179
164
180
Ref<Animation> _save_animation_to_file (Ref<Animation> anim, bool p_save_to_file, String p_save_to_path, bool p_keep_custom_tracks);
165
181
void _create_clips (AnimationPlayer *anim, const Array &p_clips, bool p_bake_all);
@@ -177,6 +193,12 @@ class ResourceImporterScene : public ResourceImporter {
177
193
virtual bool can_import_threaded () const override { return false ; }
178
194
179
195
ResourceImporterScene ();
196
+
197
+ template <class M >
198
+ static Vector<Ref<Shape3D>> get_collision_shapes (const Ref<Mesh> &p_mesh, const M &p_options);
199
+
200
+ template <class M >
201
+ static Transform3D get_collision_shapes_transform (const M &p_options);
180
202
};
181
203
182
204
class EditorSceneImporterESCN : public EditorSceneImporter {
@@ -189,4 +211,176 @@ class EditorSceneImporterESCN : public EditorSceneImporter {
189
211
virtual Ref<Animation> import_animation (const String &p_path, uint32_t p_flags, int p_bake_fps) override ;
190
212
};
191
213
214
+ #include " scene/resources/box_shape_3d.h"
215
+ #include " scene/resources/capsule_shape_3d.h"
216
+ #include " scene/resources/cylinder_shape_3d.h"
217
+ #include " scene/resources/sphere_shape_3d.h"
218
+
219
+ template <class M >
220
+ Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes (const Ref<Mesh> &p_mesh, const M &p_options) {
221
+ ShapeType generate_shape_type = SHAPE_TYPE_DECOMPOSE_CONVEX;
222
+ if (p_options.has (SNAME (" physics/shape_type" ))) {
223
+ generate_shape_type = (ShapeType)p_options[SNAME (" physics/shape_type" )].operator int ();
224
+ }
225
+
226
+ if (generate_shape_type == SHAPE_TYPE_DECOMPOSE_CONVEX) {
227
+ Mesh::ConvexDecompositionSettings decomposition_settings;
228
+ bool advanced = false ;
229
+ if (p_options.has (SNAME (" decomposition/advanced" ))) {
230
+ advanced = p_options[SNAME (" decomposition/advanced" )];
231
+ }
232
+
233
+ if (advanced) {
234
+ if (p_options.has (SNAME (" decomposition/max_concavity" ))) {
235
+ decomposition_settings.max_concavity = p_options[SNAME (" decomposition/max_concavity" )];
236
+ }
237
+
238
+ if (p_options.has (SNAME (" decomposition/symmetry_planes_clipping_bias" ))) {
239
+ decomposition_settings.symmetry_planes_clipping_bias = p_options[SNAME (" decomposition/symmetry_planes_clipping_bias" )];
240
+ }
241
+
242
+ if (p_options.has (SNAME (" decomposition/revolution_axes_clipping_bias" ))) {
243
+ decomposition_settings.revolution_axes_clipping_bias = p_options[SNAME (" decomposition/revolution_axes_clipping_bias" )];
244
+ }
245
+
246
+ if (p_options.has (SNAME (" decomposition/min_volume_per_convex_hull" ))) {
247
+ decomposition_settings.min_volume_per_convex_hull = p_options[SNAME (" decomposition/min_volume_per_convex_hull" )];
248
+ }
249
+
250
+ if (p_options.has (SNAME (" decomposition/resolution" ))) {
251
+ decomposition_settings.resolution = p_options[SNAME (" decomposition/resolution" )];
252
+ }
253
+
254
+ if (p_options.has (SNAME (" decomposition/max_num_vertices_per_convex_hull" ))) {
255
+ decomposition_settings.max_num_vertices_per_convex_hull = p_options[SNAME (" decomposition/max_num_vertices_per_convex_hull" )];
256
+ }
257
+
258
+ if (p_options.has (SNAME (" decomposition/plane_downsampling" ))) {
259
+ decomposition_settings.plane_downsampling = p_options[SNAME (" decomposition/plane_downsampling" )];
260
+ }
261
+
262
+ if (p_options.has (SNAME (" decomposition/convexhull_downsampling" ))) {
263
+ decomposition_settings.convexhull_downsampling = p_options[SNAME (" decomposition/convexhull_downsampling" )];
264
+ }
265
+
266
+ if (p_options.has (SNAME (" decomposition/normalize_mesh" ))) {
267
+ decomposition_settings.normalize_mesh = p_options[SNAME (" decomposition/normalize_mesh" )];
268
+ }
269
+
270
+ if (p_options.has (SNAME (" decomposition/mode" ))) {
271
+ decomposition_settings.mode = (Mesh::ConvexDecompositionSettings::Mode)p_options[SNAME (" decomposition/mode" )].operator int ();
272
+ }
273
+
274
+ if (p_options.has (SNAME (" decomposition/convexhull_approximation" ))) {
275
+ decomposition_settings.convexhull_approximation = p_options[SNAME (" decomposition/convexhull_approximation" )];
276
+ }
277
+
278
+ if (p_options.has (SNAME (" decomposition/max_convex_hulls" ))) {
279
+ decomposition_settings.max_convex_hulls = p_options[SNAME (" decomposition/max_convex_hulls" )];
280
+ }
281
+
282
+ if (p_options.has (SNAME (" decomposition/project_hull_vertices" ))) {
283
+ decomposition_settings.project_hull_vertices = p_options[SNAME (" decomposition/project_hull_vertices" )];
284
+ }
285
+ } else {
286
+ int precision_level = 5 ;
287
+ if (p_options.has (SNAME (" decomposition/precision" ))) {
288
+ precision_level = p_options[SNAME (" decomposition/precision" )];
289
+ }
290
+
291
+ const real_t precision = real_t (precision_level - 1 ) / 9.0 ;
292
+
293
+ decomposition_settings.max_concavity = Math::lerp (real_t (1.0 ), real_t (0.001 ), precision);
294
+ decomposition_settings.min_volume_per_convex_hull = Math::lerp (real_t (0.01 ), real_t (0.0001 ), precision);
295
+ decomposition_settings.resolution = Math::lerp (10'000 , 100'000 , precision);
296
+ decomposition_settings.max_num_vertices_per_convex_hull = Math::lerp (32 , 64 , precision);
297
+ decomposition_settings.plane_downsampling = Math::lerp (3 , 16 , precision);
298
+ decomposition_settings.convexhull_downsampling = Math::lerp (3 , 16 , precision);
299
+ decomposition_settings.max_convex_hulls = Math::lerp (1 , 32 , precision);
300
+ }
301
+
302
+ return p_mesh->convex_decompose (decomposition_settings);
303
+ } else if (generate_shape_type == SHAPE_TYPE_SIMPLE_CONVEX) {
304
+ Vector<Ref<Shape3D>> shapes;
305
+ shapes.push_back (p_mesh->create_convex_shape (true , /* Passing false, otherwise VHACD will be used to simplify (Decompose) the Mesh.*/ false ));
306
+ return shapes;
307
+ } else if (generate_shape_type == SHAPE_TYPE_TRIMESH) {
308
+ Vector<Ref<Shape3D>> shapes;
309
+ shapes.push_back (p_mesh->create_trimesh_shape ());
310
+ return shapes;
311
+ } else if (generate_shape_type == SHAPE_TYPE_BOX) {
312
+ Ref<BoxShape3D> box;
313
+ box.instantiate ();
314
+ if (p_options.has (SNAME (" primitive/size" ))) {
315
+ box->set_size (p_options[SNAME (" primitive/size" )]);
316
+ }
317
+
318
+ Vector<Ref<Shape3D>> shapes;
319
+ shapes.push_back (box);
320
+ return shapes;
321
+
322
+ } else if (generate_shape_type == SHAPE_TYPE_SPHERE) {
323
+ Ref<SphereShape3D> sphere;
324
+ sphere.instantiate ();
325
+ if (p_options.has (SNAME (" primitive/radius" ))) {
326
+ sphere->set_radius (p_options[SNAME (" primitive/radius" )]);
327
+ }
328
+
329
+ Vector<Ref<Shape3D>> shapes;
330
+ shapes.push_back (sphere);
331
+ return shapes;
332
+ } else if (generate_shape_type == SHAPE_TYPE_CYLINDER) {
333
+ Ref<CylinderShape3D> cylinder;
334
+ cylinder.instantiate ();
335
+ if (p_options.has (SNAME (" primitive/height" ))) {
336
+ cylinder->set_height (p_options[SNAME (" primitive/height" )]);
337
+ }
338
+ if (p_options.has (SNAME (" primitive/radius" ))) {
339
+ cylinder->set_radius (p_options[SNAME (" primitive/radius" )]);
340
+ }
341
+
342
+ Vector<Ref<Shape3D>> shapes;
343
+ shapes.push_back (cylinder);
344
+ return shapes;
345
+ } else if (generate_shape_type == SHAPE_TYPE_CAPSULE) {
346
+ Ref<CapsuleShape3D> capsule;
347
+ capsule.instantiate ();
348
+ if (p_options.has (SNAME (" primitive/height" ))) {
349
+ capsule->set_height (p_options[SNAME (" primitive/height" )]);
350
+ }
351
+ if (p_options.has (SNAME (" primitive/radius" ))) {
352
+ capsule->set_radius (p_options[SNAME (" primitive/radius" )]);
353
+ }
354
+
355
+ Vector<Ref<Shape3D>> shapes;
356
+ shapes.push_back (capsule);
357
+ return shapes;
358
+ }
359
+ return Vector<Ref<Shape3D>>();
360
+ }
361
+
362
+ template <class M >
363
+ Transform3D ResourceImporterScene::get_collision_shapes_transform (const M &p_options) {
364
+ Transform3D transform;
365
+
366
+ ShapeType generate_shape_type = SHAPE_TYPE_DECOMPOSE_CONVEX;
367
+ if (p_options.has (SNAME (" physics/shape_type" ))) {
368
+ generate_shape_type = (ShapeType)p_options[SNAME (" physics/shape_type" )].operator int ();
369
+ }
370
+
371
+ if (generate_shape_type == SHAPE_TYPE_BOX ||
372
+ generate_shape_type == SHAPE_TYPE_SPHERE ||
373
+ generate_shape_type == SHAPE_TYPE_CYLINDER ||
374
+ generate_shape_type == SHAPE_TYPE_CAPSULE) {
375
+ if (p_options.has (SNAME (" primitive/position" ))) {
376
+ transform.origin = p_options[SNAME (" primitive/position" )];
377
+ }
378
+
379
+ if (p_options.has (SNAME (" primitive/rotation" ))) {
380
+ transform.basis .set_euler ((p_options[SNAME (" primitive/rotation" )].operator Vector3 () / 180.0 ) * Math_PI);
381
+ }
382
+ }
383
+ return transform;
384
+ }
385
+
192
386
#endif // RESOURCEIMPORTERSCENE_H
0 commit comments