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