Goodevil95

3.2 import hints

May 31st, 2020
431
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 28.60 KB | None | 0 0
  1. diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
  2. index 3ae69d8..89ded65 100644
  3. --- a/editor/import/resource_importer_scene.cpp
  4. +++ b/editor/import/resource_importer_scene.cpp
  5. @@ -236,55 +236,12 @@ String ResourceImporterScene::get_preset_name(int p_idx) const {
  6.     return "";
  7.  }
  8.  
  9. -static bool _teststr(const String &p_what, const String &p_str) {
  10. -
  11. -   String what = p_what;
  12. -
  13. -   //remove trailing spaces and numbers, some apps like blender add ".number" to duplicates so also compensate for this
  14. -   while (what.length() && ((what[what.length() - 1] >= '0' && what[what.length() - 1] <= '9') || what[what.length() - 1] <= 32 || what[what.length() - 1] == '.')) {
  15. -
  16. -       what = what.substr(0, what.length() - 1);
  17. -   }
  18. -
  19. -   if (what.findn("$" + p_str) != -1) //blender and other stuff
  20. -       return true;
  21. -   if (what.to_lower().ends_with("-" + p_str)) //collada only supports "_" and "-" besides letters
  22. -       return true;
  23. -   if (what.to_lower().ends_with("_" + p_str)) //collada only supports "_" and "-" besides letters
  24. -       return true;
  25. -   return false;
  26. -}
  27. -
  28. -static String _fixstr(const String &p_what, const String &p_str) {
  29. -
  30. -   String what = p_what;
  31. -
  32. -   //remove trailing spaces and numbers, some apps like blender add ".number" to duplicates so also compensate for this
  33. -   while (what.length() && ((what[what.length() - 1] >= '0' && what[what.length() - 1] <= '9') || what[what.length() - 1] <= 32 || what[what.length() - 1] == '.')) {
  34. -
  35. -       what = what.substr(0, what.length() - 1);
  36. -   }
  37. -
  38. -   String end = p_what.substr(what.length(), p_what.length() - what.length());
  39. -
  40. -   if (what.findn("$" + p_str) != -1) //blender and other stuff
  41. -       return what.replace("$" + p_str, "") + end;
  42. -   if (what.to_lower().ends_with("-" + p_str)) //collada only supports "_" and "-" besides letters
  43. -       return what.substr(0, what.length() - (p_str.length() + 1)) + end;
  44. -   if (what.to_lower().ends_with("_" + p_str)) //collada only supports "_" and "-" besides letters
  45. -       return what.substr(0, what.length() - (p_str.length() + 1)) + end;
  46. -   return what;
  47. -}
  48. -
  49. -static void _gen_shape_list(const Ref<Mesh> &mesh, List<Ref<Shape> > &r_shape_list, bool p_convex) {
  50. -
  51. +void ResourceImporterScene::_gen_shape_list(const Ref<Mesh> &p_mesh, List<Ref<Shape>> &r_shape_list, bool p_convex) {
  52.     if (!p_convex) {
  53. -
  54. -       Ref<Shape> shape = mesh->create_trimesh_shape();
  55. +       Ref<Shape> shape = p_mesh->create_trimesh_shape();
  56.         r_shape_list.push_back(shape);
  57.     } else {
  58. -
  59. -       Vector<Ref<Shape> > cd = mesh->convex_decompose();
  60. +       Vector<Ref<Shape>> cd = p_mesh->convex_decompose();
  61.         if (cd.size()) {
  62.             for (int i = 0; i < cd.size(); i++) {
  63.                 r_shape_list.push_back(cd[i]);
  64. @@ -293,182 +250,100 @@ static void _gen_shape_list(const Ref<Mesh> &mesh, List<Ref<Shape> > &r_shape_li
  65.     }
  66.  }
  67.  
  68. -Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape> > > &collision_map, LightBakeMode p_light_bake_mode) {
  69. -
  70. +Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape>>> &collision_map, LightBakeMode p_light_bake_mode) {
  71.     // children first
  72.     for (int i = 0; i < p_node->get_child_count(); i++) {
  73. -
  74.         Node *r = _fix_node(p_node->get_child(i), p_root, collision_map, p_light_bake_mode);
  75.         if (!r) {
  76.             i--; //was erased
  77.         }
  78.     }
  79.  
  80. -   String name = p_node->get_name();
  81. -
  82. -   bool isroot = p_node == p_root;
  83. -
  84. -   if (!isroot && _teststr(name, "noimp")) {
  85. +   const auto [node_name, node_hint] = _get_node_import_hint(p_node->get_name());
  86. +   const bool is_root = p_node == p_root;
  87.  
  88. +   if (!is_root && node_hint == NODE_HINT_NO_IMPORT) {
  89.         memdelete(p_node);
  90. -       return NULL;
  91. +       return nullptr;
  92.     }
  93.  
  94. -   if (Object::cast_to<MeshInstance>(p_node)) {
  95. -
  96. -       MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
  97. -
  98. -       Ref<ArrayMesh> m = mi->get_mesh();
  99. -
  100. -       if (m.is_valid()) {
  101. -
  102. -           for (int i = 0; i < m->get_surface_count(); i++) {
  103. -
  104. -               Ref<SpatialMaterial> mat = m->surface_get_material(i);
  105. -               if (!mat.is_valid())
  106. -                   continue;
  107. -
  108. -               if (_teststr(mat->get_name(), "alpha")) {
  109. -
  110. -                   mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  111. -                   mat->set_name(_fixstr(mat->get_name(), "alpha"));
  112. -               }
  113. -               if (_teststr(mat->get_name(), "vcol")) {
  114. -
  115. -                   mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
  116. -                   mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
  117. -                   mat->set_name(_fixstr(mat->get_name(), "vcol"));
  118. -               }
  119. -           }
  120. -       }
  121. -
  122. -       if (p_light_bake_mode != LIGHT_BAKE_DISABLED) {
  123. -
  124. -           mi->set_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT, true);
  125. -       }
  126. +   if (auto *ap = Object::cast_to<AnimationPlayer>(p_node); ap) {
  127. +       _fix_animations(ap);
  128. +       return p_node;
  129.     }
  130.  
  131. -   if (Object::cast_to<AnimationPlayer>(p_node)) {
  132. -       //remove animations referencing non-importable nodes
  133. -       AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
  134. -
  135. -       List<StringName> anims;
  136. -       ap->get_animation_list(&anims);
  137. -       for (List<StringName>::Element *E = anims.front(); E; E = E->next()) {
  138. -
  139. -           Ref<Animation> anim = ap->get_animation(E->get());
  140. -           ERR_CONTINUE(anim.is_null());
  141. -           for (int i = 0; i < anim->get_track_count(); i++) {
  142. -               NodePath path = anim->track_get_path(i);
  143. -
  144. -               for (int j = 0; j < path.get_name_count(); j++) {
  145. -                   String node = path.get_name(j);
  146. -                   if (_teststr(node, "noimp")) {
  147. -                       anim->remove_track(i);
  148. -                       i--;
  149. -                       break;
  150. -                   }
  151. -               }
  152. -           }
  153. -       }
  154. +   auto *mesh_instance = Object::cast_to<MeshInstance>(p_node);
  155. +   if (mesh_instance) {
  156. +       _fix_materials(mesh_instance, p_light_bake_mode);
  157.     }
  158.  
  159. -   if (_teststr(name, "colonly") || _teststr(name, "convcolonly")) {
  160. -
  161. -       if (isroot)
  162. +   if (node_hint == NODE_HINT_COLLISION_ONLY || node_hint == NODE_HINT_CONVEX_COLLISION_ONLY || node_hint == NODE_HINT_SHAPE_ONLY || node_hint == NODE_HINT_CONVEX_SHAPE_ONLY) {
  163. +       if (is_root) {
  164.             return p_node;
  165. -       MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
  166. -       if (mi) {
  167. -           Ref<Mesh> mesh = mi->get_mesh();
  168. +       }
  169. +       if (mesh_instance) {
  170. +           Ref<Mesh> mesh = mesh_instance->get_mesh();
  171.  
  172.             if (mesh.is_valid()) {
  173. -               List<Ref<Shape> > shapes;
  174. -               String fixed_name;
  175. +               List<Ref<Shape>> shapes;
  176.                 if (collision_map.has(mesh)) {
  177.                     shapes = collision_map[mesh];
  178. -               } else if (_teststr(name, "colonly")) {
  179. -                   _gen_shape_list(mesh, shapes, false);
  180. -                   collision_map[mesh] = shapes;
  181. -               } else if (_teststr(name, "convcolonly")) {
  182. -                   _gen_shape_list(mesh, shapes, true);
  183. +               } else {
  184. +                   _gen_shape_list(mesh, shapes, node_hint == NODE_HINT_CONVEX_COLLISION_ONLY || node_hint == NODE_HINT_CONVEX_SHAPE_ONLY);
  185.                     collision_map[mesh] = shapes;
  186.                 }
  187.  
  188. -               if (_teststr(name, "colonly")) {
  189. -                   fixed_name = _fixstr(name, "colonly");
  190. -               } else if (_teststr(name, "convcolonly")) {
  191. -                   fixed_name = _fixstr(name, "convcolonly");
  192. -               }
  193. -
  194. -               ERR_FAIL_COND_V(fixed_name == String(), NULL);
  195. +               ERR_FAIL_COND_V(node_name == String(), nullptr);
  196.  
  197.                 if (shapes.size()) {
  198. -
  199. -                   StaticBody *col = memnew(StaticBody);
  200. -                   col->set_transform(mi->get_transform());
  201. -                   col->set_name(fixed_name);
  202. -                   p_node->replace_by(col);
  203. -                   memdelete(p_node);
  204. -                   p_node = col;
  205. -
  206. -                   int idx = 0;
  207. -                   for (List<Ref<Shape> >::Element *E = shapes.front(); E; E = E->next()) {
  208. -
  209. -                       CollisionShape *cshape = memnew(CollisionShape);
  210. -                       cshape->set_shape(E->get());
  211. -                       col->add_child(cshape);
  212. -
  213. -                       cshape->set_name("shape" + itos(idx));
  214. -                       cshape->set_owner(col->get_owner());
  215. -                       idx++;
  216. +                   if (node_hint == NODE_HINT_COLLISION_ONLY || node_hint == NODE_HINT_CONVEX_COLLISION_ONLY) {
  217. +                       StaticBody *static_body = memnew(StaticBody);
  218. +                       static_body->set_transform(mesh_instance->get_transform());
  219. +                       static_body->set_name(node_name);
  220. +                       p_node->replace_by(static_body);
  221. +                       memdelete(p_node);
  222. +                       p_node = static_body;
  223. +
  224. +                       _add_shapes(static_body, shapes);
  225. +                   } else {
  226. +                       _add_shapes(p_root, shapes, node_name);
  227. +                       memdelete(p_node);
  228. +                       p_node = nullptr;
  229.                     }
  230.                 }
  231.             }
  232.  
  233. -       } else if (p_node->has_meta("empty_draw_type")) {
  234. -           String empty_draw_type = String(p_node->get_meta("empty_draw_type"));
  235. -           StaticBody *sb = memnew(StaticBody);
  236. -           sb->set_name(_fixstr(name, "colonly"));
  237. -           Object::cast_to<Spatial>(sb)->set_transform(Object::cast_to<Spatial>(p_node)->get_transform());
  238. -           p_node->replace_by(sb);
  239. -           memdelete(p_node);
  240. -           p_node = NULL;
  241. -           CollisionShape *colshape = memnew(CollisionShape);
  242. -           if (empty_draw_type == "CUBE") {
  243. -               BoxShape *boxShape = memnew(BoxShape);
  244. -               boxShape->set_extents(Vector3(1, 1, 1));
  245. -               colshape->set_shape(boxShape);
  246. -               colshape->set_name("BoxShape");
  247. -           } else if (empty_draw_type == "SINGLE_ARROW") {
  248. -               RayShape *rayShape = memnew(RayShape);
  249. -               rayShape->set_length(1);
  250. -               colshape->set_shape(rayShape);
  251. -               colshape->set_name("RayShape");
  252. -               Object::cast_to<Spatial>(sb)->rotate_x(Math_PI / 2);
  253. -           } else if (empty_draw_type == "IMAGE") {
  254. -               PlaneShape *planeShape = memnew(PlaneShape);
  255. -               colshape->set_shape(planeShape);
  256. -               colshape->set_name("PlaneShape");
  257. +       } else if (CollisionShape *colshape = _shape_from_empty_meta(p_node); colshape) {
  258. +           if (node_hint == NODE_HINT_COLLISION_ONLY || node_hint == NODE_HINT_CONVEX_COLLISION_ONLY) {
  259. +               StaticBody *static_body = memnew(StaticBody);
  260. +               static_body->set_name(node_name);
  261. +               p_node->replace_by(static_body);
  262. +               memdelete(p_node);
  263. +               p_node = static_body;
  264. +
  265. +               static_body->set_transform(Object::cast_to<Spatial>(p_node)->get_transform());
  266. +               if (Object::cast_to<RayShape>(*colshape->get_shape())) {
  267. +                   static_body->rotate_x(Math_PI / 2);
  268. +               }
  269. +
  270. +               static_body->add_child(colshape);
  271. +               colshape->set_owner(static_body->get_owner());
  272.             } else {
  273. -               SphereShape *sphereShape = memnew(SphereShape);
  274. -               sphereShape->set_radius(1);
  275. -               colshape->set_shape(sphereShape);
  276. -               colshape->set_name("SphereShape");
  277. +               p_node->replace_by(colshape);
  278. +               memdelete(p_node);
  279. +               p_node = colshape;
  280.             }
  281. -           sb->add_child(colshape);
  282. -           colshape->set_owner(sb->get_owner());
  283.         }
  284.  
  285. -   } else if (_teststr(name, "rigid") && Object::cast_to<MeshInstance>(p_node)) {
  286. -
  287. -       if (isroot)
  288. +   } else if (node_hint == NODE_HINT_RIGID && mesh_instance) {
  289. +       if (is_root) {
  290.             return p_node;
  291. +       }
  292.  
  293. -       MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
  294. -       Ref<Mesh> mesh = mi->get_mesh();
  295. +       Ref<Mesh> mesh = mesh_instance->get_mesh();
  296.  
  297.         if (mesh.is_valid()) {
  298. -           List<Ref<Shape> > shapes;
  299. +           List<Ref<Shape>> shapes;
  300.             if (collision_map.has(mesh)) {
  301.                 shapes = collision_map[mesh];
  302.             } else {
  303. @@ -476,177 +351,138 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
  304.             }
  305.  
  306.             RigidBody *rigid_body = memnew(RigidBody);
  307. -           rigid_body->set_name(_fixstr(name, "rigid"));
  308. +           rigid_body->set_name(node_name);
  309.             p_node->replace_by(rigid_body);
  310. -           rigid_body->set_transform(mi->get_transform());
  311. +           rigid_body->set_transform(mesh_instance->get_transform());
  312.             p_node = rigid_body;
  313. -           mi->set_name("mesh");
  314. -           mi->set_transform(Transform());
  315. -           rigid_body->add_child(mi);
  316. -           mi->set_owner(rigid_body->get_owner());
  317. -
  318. -           int idx = 0;
  319. -           for (List<Ref<Shape> >::Element *E = shapes.front(); E; E = E->next()) {
  320. -
  321. -               CollisionShape *cshape = memnew(CollisionShape);
  322. -               cshape->set_shape(E->get());
  323. -               rigid_body->add_child(cshape);
  324. +           mesh_instance->set_transform(Transform());
  325. +           rigid_body->add_child(mesh_instance);
  326. +           mesh_instance->set_owner(rigid_body->get_owner());
  327.  
  328. -               cshape->set_name("shape" + itos(idx));
  329. -               cshape->set_owner(p_node->get_owner());
  330. -               idx++;
  331. -           }
  332. +           _add_shapes(rigid_body, shapes);
  333.         }
  334.  
  335. -   } else if ((_teststr(name, "col") || (_teststr(name, "convcol"))) && Object::cast_to<MeshInstance>(p_node)) {
  336. -
  337. -       MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
  338. -
  339. -       Ref<Mesh> mesh = mi->get_mesh();
  340. +   } else if ((node_hint == NODE_HINT_COLLISION || node_hint == NODE_HINT_CONVEX_COLLISION || node_hint == NODE_HINT_SHAPE || node_hint == NODE_HINT_CONVEX_SHAPE) && mesh_instance) {
  341. +       Ref<Mesh> mesh = mesh_instance->get_mesh();
  342.  
  343.         if (mesh.is_valid()) {
  344. -           List<Ref<Shape> > shapes;
  345. -           String fixed_name;
  346. +           List<Ref<Shape>> shapes;
  347.             if (collision_map.has(mesh)) {
  348.                 shapes = collision_map[mesh];
  349. -           } else if (_teststr(name, "col")) {
  350. -               _gen_shape_list(mesh, shapes, false);
  351. -               collision_map[mesh] = shapes;
  352. -           } else if (_teststr(name, "convcol")) {
  353. -               _gen_shape_list(mesh, shapes, true);
  354. +           } else {
  355. +               _gen_shape_list(mesh, shapes, node_hint == NODE_HINT_CONVEX_COLLISION || node_hint == NODE_HINT_CONVEX_SHAPE);
  356.                 collision_map[mesh] = shapes;
  357.             }
  358.  
  359. -           if (_teststr(name, "col")) {
  360. -               fixed_name = _fixstr(name, "col");
  361. -           } else if (_teststr(name, "convcol")) {
  362. -               fixed_name = _fixstr(name, "convcol");
  363. -           }
  364. -
  365. -           if (fixed_name != String()) {
  366. -               if (mi->get_parent() && !mi->get_parent()->has_node(fixed_name)) {
  367. -                   mi->set_name(fixed_name);
  368. +           if (node_name != String()) {
  369. +               if (mesh_instance->get_parent()) {
  370. +                   mesh_instance->set_name(node_name);
  371.                 }
  372.             }
  373.  
  374.             if (shapes.size()) {
  375. -               StaticBody *col = memnew(StaticBody);
  376. -               col->set_name("static_collision");
  377. -               mi->add_child(col);
  378. -               col->set_owner(mi->get_owner());
  379. -
  380. -               int idx = 0;
  381. -               for (List<Ref<Shape> >::Element *E = shapes.front(); E; E = E->next()) {
  382. -
  383. -                   CollisionShape *cshape = memnew(CollisionShape);
  384. -                   cshape->set_shape(E->get());
  385. -                   col->add_child(cshape);
  386. -
  387. -                   cshape->set_name("shape" + itos(idx));
  388. -                   cshape->set_owner(p_node->get_owner());
  389. -
  390. -                   idx++;
  391. +               if (node_hint == NODE_HINT_COLLISION || node_hint == NODE_HINT_CONVEX_COLLISION) {
  392. +                   StaticBody *static_body = memnew(StaticBody);
  393. +                   mesh_instance->add_child(static_body);
  394. +                   static_body->set_owner(mesh_instance->get_owner());
  395. +
  396. +                   _add_shapes(static_body, shapes);
  397. +               } else {
  398. +                   switch (ProjectSettings::get_singleton()->get("node/name_casing").operator int()) {
  399. +                       case Node::NAME_CASING_PASCAL_CASE:
  400. +                       case Node::NAME_CASING_CAMEL_CASE:
  401. +                           _add_shapes(p_root, shapes, node_name + "Shape");
  402. +                           break;
  403. +                       case Node::NAME_CASING_SNAKE_CASE:
  404. +                           _add_shapes(p_root, shapes, node_name + "_shape");
  405. +                           break;
  406. +                   }
  407.                 }
  408.             }
  409.         }
  410.  
  411. -   } else if (_teststr(name, "navmesh") && Object::cast_to<MeshInstance>(p_node)) {
  412. -
  413. -       if (isroot)
  414. +   } else if (node_hint == NODE_HINT_NAVMESH && mesh_instance) {
  415. +       if (is_root) {
  416.             return p_node;
  417. +       }
  418.  
  419. -       MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
  420. -
  421. -       Ref<ArrayMesh> mesh = mi->get_mesh();
  422. -       ERR_FAIL_COND_V(mesh.is_null(), NULL);
  423. +       Ref<ArrayMesh> mesh = mesh_instance->get_mesh();
  424. +       ERR_FAIL_COND_V(mesh.is_null(), nullptr);
  425.         NavigationMeshInstance *nmi = memnew(NavigationMeshInstance);
  426.  
  427. -       nmi->set_name(_fixstr(name, "navmesh"));
  428. +       nmi->set_name(node_name);
  429.         Ref<NavigationMesh> nmesh = memnew(NavigationMesh);
  430.         nmesh->create_from_mesh(mesh);
  431.         nmi->set_navigation_mesh(nmesh);
  432. -       Object::cast_to<Spatial>(nmi)->set_transform(mi->get_transform());
  433. +       Object::cast_to<Spatial>(nmi)->set_transform(mesh_instance->get_transform());
  434.         p_node->replace_by(nmi);
  435.         memdelete(p_node);
  436.         p_node = nmi;
  437. -   } else if (_teststr(name, "vehicle")) {
  438. -
  439. -       if (isroot)
  440. +   } else if (node_hint == NODE_HINT_VEHICLE) {
  441. +       if (p_node != p_root) {
  442.             return p_node;
  443. +       }
  444.  
  445.         Node *owner = p_node->get_owner();
  446. -       Spatial *s = Object::cast_to<Spatial>(p_node);
  447. -       VehicleBody *bv = memnew(VehicleBody);
  448. -       String n = _fixstr(p_node->get_name(), "vehicle");
  449. -       bv->set_name(n);
  450. -       p_node->replace_by(bv);
  451. -       p_node->set_name(n);
  452. -       bv->add_child(p_node);
  453. -       bv->set_owner(owner);
  454. +       Spatial *spatial = Object::cast_to<Spatial>(p_node);
  455. +       VehicleBody *vehicle_body = memnew(VehicleBody);
  456. +       vehicle_body->set_name(node_name);
  457. +       p_node->replace_by(vehicle_body);
  458. +       p_node->set_name(node_name);
  459. +       vehicle_body->add_child(p_node);
  460. +       vehicle_body->set_owner(owner);
  461.         p_node->set_owner(owner);
  462. -       bv->set_transform(s->get_transform());
  463. -       s->set_transform(Transform());
  464. +       vehicle_body->set_transform(spatial->get_transform());
  465. +       spatial->set_transform(Transform());
  466.  
  467. -       p_node = bv;
  468. +       p_node = vehicle_body;
  469.  
  470. -   } else if (_teststr(name, "wheel")) {
  471. -
  472. -       if (isroot)
  473. +   } else if (node_hint == NODE_HINT_WHEEL) {
  474. +       if (is_root) {
  475.             return p_node;
  476. +       }
  477.  
  478.         Node *owner = p_node->get_owner();
  479. -       Spatial *s = Object::cast_to<Spatial>(p_node);
  480. -       VehicleWheel *bv = memnew(VehicleWheel);
  481. -       String n = _fixstr(p_node->get_name(), "wheel");
  482. -       bv->set_name(n);
  483. -       p_node->replace_by(bv);
  484. -       p_node->set_name(n);
  485. -       bv->add_child(p_node);
  486. -       bv->set_owner(owner);
  487. +       Spatial *spatial = Object::cast_to<Spatial>(p_node);
  488. +       VehicleWheel *vehicle_wheel = memnew(VehicleWheel);
  489. +       vehicle_wheel->set_name(node_name);
  490. +       p_node->replace_by(vehicle_wheel);
  491. +       p_node->set_name(node_name);
  492. +       vehicle_wheel->add_child(p_node);
  493. +       vehicle_wheel->set_owner(owner);
  494.         p_node->set_owner(owner);
  495. -       bv->set_transform(s->get_transform());
  496. -       s->set_transform(Transform());
  497. +       vehicle_wheel->set_transform(spatial->get_transform());
  498. +       spatial->set_transform(Transform());
  499.  
  500. -       p_node = bv;
  501. -
  502. -   } else if (Object::cast_to<MeshInstance>(p_node)) {
  503. +       p_node = vehicle_wheel;
  504.  
  505. +   } else if (mesh_instance) {
  506.         //last attempt, maybe collision inside the mesh data
  507. -
  508. -       MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
  509. -
  510. -       Ref<ArrayMesh> mesh = mi->get_mesh();
  511. +       Ref<ArrayMesh> mesh = mesh_instance->get_mesh();
  512.         if (!mesh.is_null()) {
  513. -
  514. -           List<Ref<Shape> > shapes;
  515. +           auto [mesh_name, mesh_hint] = _get_node_import_hint(mesh->get_name());
  516. +           List<Ref<Shape>> shapes;
  517.             if (collision_map.has(mesh)) {
  518.                 shapes = collision_map[mesh];
  519. -           } else if (_teststr(mesh->get_name(), "col")) {
  520. +           } else if (mesh_hint == NODE_HINT_COLLISION) {
  521.                 _gen_shape_list(mesh, shapes, false);
  522.                 collision_map[mesh] = shapes;
  523. -               mesh->set_name(_fixstr(mesh->get_name(), "col"));
  524. -           } else if (_teststr(mesh->get_name(), "convcol")) {
  525. +               mesh->set_name(mesh_name);
  526. +           } else if (mesh_hint == NODE_HINT_CONVEX_COLLISION) {
  527.                 _gen_shape_list(mesh, shapes, true);
  528.                 collision_map[mesh] = shapes;
  529. -               mesh->set_name(_fixstr(mesh->get_name(), "convcol"));
  530. +               mesh->set_name(node_name);
  531.             }
  532.  
  533.             if (shapes.size()) {
  534. -               StaticBody *col = memnew(StaticBody);
  535. -               col->set_name("static_collision");
  536. -               p_node->add_child(col);
  537. -               col->set_owner(p_node->get_owner());
  538. -
  539. -               int idx = 0;
  540. -               for (List<Ref<Shape> >::Element *E = shapes.front(); E; E = E->next()) {
  541. -
  542. -                   CollisionShape *cshape = memnew(CollisionShape);
  543. -                   cshape->set_shape(E->get());
  544. -                   col->add_child(cshape);
  545. -
  546. -                   cshape->set_name("shape" + itos(idx));
  547. -                   cshape->set_owner(p_node->get_owner());
  548. -                   idx++;
  549. +               if (mesh_hint == NODE_HINT_COLLISION || mesh_hint == NODE_HINT_CONVEX_COLLISION) {
  550. +                   StaticBody *static_body = memnew(StaticBody);
  551. +                   p_node->add_child(static_body);
  552. +                   static_body->set_owner(p_node->get_owner());
  553. +
  554. +                   _add_shapes(static_body, shapes);
  555. +               } else {
  556. +                   _add_shapes(p_root, shapes);
  557.                 }
  558.             }
  559.         }
  560. @@ -1192,6 +1028,98 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
  561.     }
  562.  }
  563.  
  564. +String ResourceImporterScene::_import_hint_string(ResourceImporterScene::NodeHints p_hint) {
  565. +   switch (p_hint) {
  566. +       case NODE_HINT_NONE:
  567. +           return "";
  568. +       case NODE_HINT_NO_IMPORT:
  569. +           return "noimp";
  570. +       case NODE_HINT_COLLISION:
  571. +           return "col";
  572. +       case NODE_HINT_CONVEX_COLLISION:
  573. +           return "convcol";
  574. +       case NODE_HINT_COLLISION_ONLY:
  575. +           return "colonly";
  576. +       case NODE_HINT_CONVEX_COLLISION_ONLY:
  577. +           return "convcolonly";
  578. +       case NODE_HINT_SHAPE:
  579. +           return "shape";
  580. +       case NODE_HINT_CONVEX_SHAPE:
  581. +           return "convshape";
  582. +       case NODE_HINT_SHAPE_ONLY:
  583. +           return "shapeonly";
  584. +       case NODE_HINT_CONVEX_SHAPE_ONLY:
  585. +           return "convshapeonly";
  586. +       case NODE_HINT_RIGID:
  587. +           return "rigid";
  588. +       case NODE_HINT_NAVMESH:
  589. +           return "navmesh";
  590. +       case NODE_HINT_VEHICLE:
  591. +           return "vehicle";
  592. +       case NODE_HINT_WHEEL:
  593. +           return "wheel";
  594. +       default:
  595. +           ERR_FAIL_V_MSG(String(), "Node import hint out of range");
  596. +   }
  597. +}
  598. +
  599. +String ResourceImporterScene::_import_hint_string(ResourceImporterScene::MaterialHints p_hint) {
  600. +   switch (p_hint) {
  601. +       case MATERIAL_HINT_ALPHA:
  602. +           return "alpha";
  603. +       case MATERIAL_HINT_VERTEX_COLOR:
  604. +           return "vcol";
  605. +       default:
  606. +           ERR_FAIL_V_MSG(String(), "Material import hint out of range");
  607. +   }
  608. +}
  609. +
  610. +Pair<String, ResourceImporterScene::NodeHints> ResourceImporterScene::_get_node_import_hint(String p_name) {
  611. +   for (int enum_index = 1; enum_index < NODE_HINT_LAST; ++enum_index) {
  612. +       auto hint = static_cast<NodeHints>(enum_index);
  613. +       String hint_suffix = '-' + _import_hint_string(hint);
  614. +       if (p_name.ends_with(hint_suffix)) {
  615. +           p_name.erase(p_name.length() - hint_suffix.length(), hint_suffix.size() - 1);
  616. +           return { p_name, hint };
  617. +       }
  618. +   }
  619. +   return { p_name, NODE_HINT_NONE };
  620. +}
  621. +
  622. +Pair<String, Vector<ResourceImporterScene::MaterialHints>> ResourceImporterScene::_get_material_import_hints(const String &p_name) {
  623. +   Vector<MaterialHints> hints;
  624. +   Vector<String> name_parts = p_name.split("-");
  625. +   for (int enum_index = 1; enum_index < MATERIAL_HINT_LAST; ++enum_index) {
  626. +       auto hint = static_cast<MaterialHints>(enum_index);
  627. +       int part_index = name_parts.find(_import_hint_string(hint));
  628. +       if (part_index != -1) {
  629. +           hints.push_back(hint);
  630. +           name_parts.remove(part_index);
  631. +       }
  632. +   }
  633. +
  634. +   String fixed_name;
  635. +   for (int i = 0; i < name_parts.size(); ++i) {
  636. +       fixed_name += name_parts[i];
  637. +       if (i != 0)
  638. +           fixed_name += '-';
  639. +   }
  640. +
  641. +   return { fixed_name, hints };
  642. +}
  643. +
  644. +void ResourceImporterScene::_add_shapes(Node *p_node, List<Ref<Shape>> p_shapes, const String &basename) {
  645. +   for (List<Ref<Shape>>::Element *E = p_shapes.front(); E; E = E->next()) {
  646. +       CollisionShape *cshape = memnew(CollisionShape);
  647. +       cshape->set_shape(E->get());
  648. +       if (!basename.empty())
  649. +           cshape->set_name(basename);
  650. +
  651. +       p_node->add_child(cshape);
  652. +       cshape->set_owner(p_node->get_owner() ? p_node->get_owner() : p_node);
  653. +   }
  654. +}
  655. +
  656.  void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner) {
  657.  
  658.     if (p_node != p_new_owner && p_node->get_owner() == p_scene) {
  659. @@ -1204,6 +1132,86 @@ void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_
  660.     }
  661.  }
  662.  
  663. +CollisionShape *ResourceImporterScene::_shape_from_empty_meta(Node *p_node) {
  664. +   if (!p_node->has_meta("empty_draw_type")) {
  665. +       return nullptr;
  666. +   }
  667. +
  668. +   const String empty_draw_type = p_node->get_meta("empty_draw_type");
  669. +   CollisionShape *colshape = memnew(CollisionShape);
  670. +   if (empty_draw_type == "CUBE") {
  671. +       BoxShape *box_shape = memnew(BoxShape);
  672. +       box_shape->set_extents(Vector3(1, 1, 1));
  673. +       colshape->set_shape(box_shape);
  674. +   } else if (empty_draw_type == "SINGLE_ARROW") {
  675. +       RayShape *ray_shape = memnew(RayShape);
  676. +       ray_shape->set_length(1);
  677. +       colshape->set_shape(ray_shape);
  678. +   } else if (empty_draw_type == "IMAGE") {
  679. +       PlaneShape *plane_shape = memnew(PlaneShape);
  680. +       colshape->set_shape(plane_shape);
  681. +   } else {
  682. +       SphereShape *sphere_shape = memnew(SphereShape);
  683. +       sphere_shape->set_radius(1);
  684. +       colshape->set_shape(sphere_shape);
  685. +   }
  686. +
  687. +   return colshape;
  688. +}
  689. +
  690. +void ResourceImporterScene::_fix_materials(MeshInstance *p_mesh, LightBakeMode p_light_bake_mode) {
  691. +   Ref<ArrayMesh> array_mesh = p_mesh->get_mesh();
  692. +   if (array_mesh.is_valid()) {
  693. +       for (int surface_index = 0; surface_index < array_mesh->get_surface_count(); ++surface_index) {
  694. +           Ref<SpatialMaterial> mat = array_mesh->surface_get_material(surface_index);
  695. +           if (!mat.is_valid()) {
  696. +               continue;
  697. +           }
  698. +
  699. +           auto [material_name, material_hints] = _get_material_import_hints(mat->get_name());
  700. +           for (int hint_index = 0; hint_index < material_hints.size(); ++hint_index) {
  701. +               switch (material_hints[hint_index]) {
  702. +                   case MATERIAL_HINT_ALPHA:
  703. +                       mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  704. +                       break;
  705. +                   case MATERIAL_HINT_VERTEX_COLOR:
  706. +                       mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
  707. +                       mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
  708. +                       break;
  709. +                   default:
  710. +                       break;
  711. +               }
  712. +           }
  713. +           mat->set_name(material_name);
  714. +       }
  715. +   }
  716. +
  717. +   if (p_light_bake_mode != LIGHT_BAKE_DISABLED) {
  718. +       p_mesh->set_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT, true);
  719. +   }
  720. +}
  721. +
  722. +void ResourceImporterScene::_fix_animations(AnimationPlayer *p_player) {
  723. +   //remove animations referencing non-importable nodes
  724. +   List<StringName> anims;
  725. +   p_player->get_animation_list(&anims);
  726. +   for (List<StringName>::Element *E = anims.front(); E; E = E->next()) {
  727. +       Ref<Animation> anim = p_player->get_animation(E->get());
  728. +       ERR_CONTINUE(anim.is_null());
  729. +       for (int i = 0; i < anim->get_track_count(); i++) {
  730. +           NodePath path = anim->track_get_path(i);
  731. +
  732. +           for (int j = 0; j < path.get_name_count(); j++) {
  733. +               if (_get_node_import_hint(path.get_name(j)).second == NODE_HINT_NO_IMPORT) {
  734. +                   anim->remove_track(i);
  735. +                   i--;
  736. +                   break;
  737. +               }
  738. +           }
  739. +       }
  740. +   }
  741. +}
  742. +
  743.  Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps) {
  744.  
  745.     Ref<EditorSceneImporter> importer;
  746. diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
  747. index 20e7af1..03e0d29 100644
  748. --- a/editor/import/resource_importer_scene.h
  749. +++ b/editor/import/resource_importer_scene.h
  750. @@ -36,7 +36,10 @@
  751.  #include "scene/resources/mesh.h"
  752.  #include "scene/resources/shape.h"
  753.  
  754. +class AnimationPlayer;
  755.  class Material;
  756. +class MeshInstance;
  757. +class CollisionShape;
  758.  
  759.  class EditorSceneImporter : public Reference {
  760.  
  761. @@ -120,7 +123,44 @@ class ResourceImporterScene : public ResourceImporter {
  762.         LIGHT_BAKE_LIGHTMAPS
  763.     };
  764.  
  765. -   void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner);
  766. +   enum NodeHints {
  767. +       NODE_HINT_NONE,
  768. +       NODE_HINT_NO_IMPORT,
  769. +       NODE_HINT_COLLISION,
  770. +       NODE_HINT_CONVEX_COLLISION,
  771. +       NODE_HINT_COLLISION_ONLY,
  772. +       NODE_HINT_CONVEX_COLLISION_ONLY,
  773. +       NODE_HINT_SHAPE,
  774. +       NODE_HINT_CONVEX_SHAPE,
  775. +       NODE_HINT_SHAPE_ONLY,
  776. +       NODE_HINT_CONVEX_SHAPE_ONLY,
  777. +       NODE_HINT_RIGID,
  778. +       NODE_HINT_NAVMESH,
  779. +       NODE_HINT_VEHICLE,
  780. +       NODE_HINT_WHEEL,
  781. +       NODE_HINT_LAST,
  782. +   };
  783. +
  784. +   enum MaterialHints {
  785. +       MATERIAL_HINT_NONE,
  786. +       MATERIAL_HINT_ALPHA,
  787. +       MATERIAL_HINT_VERTEX_COLOR,
  788. +       MATERIAL_HINT_LAST,
  789. +   };
  790. +
  791. +   static String _import_hint_string(NodeHints p_hint);
  792. +   static String _import_hint_string(MaterialHints p_hint);
  793. +
  794. +   static Pair<String, NodeHints> _get_node_import_hint(String p_name);
  795. +   static Pair<String, Vector<MaterialHints>> _get_material_import_hints(const String &p_name);
  796. +
  797. +   static void _gen_shape_list(const Ref<Mesh> &p_mesh, List<Ref<Shape>> &r_shape_list, bool p_convex);
  798. +   static void _add_shapes(Node *p_node, List<Ref<Shape>> p_shapes, const String &basename = {});
  799. +   static void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner);
  800. +   static CollisionShape *_shape_from_empty_meta(Node *p_node);
  801. +
  802. +   static void _fix_materials(MeshInstance *p_mesh, LightBakeMode p_light_bake_mode);
  803. +   static void _fix_animations(AnimationPlayer *p_player);
  804.  
  805.  public:
  806.     static ResourceImporterScene *get_singleton() { return singleton; }
  807. @@ -147,7 +187,7 @@ public:
  808.  
  809.     void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_animations_as_text, bool p_keep_animations, bool p_make_materials, bool p_materials_as_text, bool p_keep_materials, bool p_make_meshes, bool p_meshes_as_text, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes);
  810.  
  811. -   Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape> > > &collision_map, LightBakeMode p_light_bake_mode);
  812. +   Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape>>> &collision_map, LightBakeMode p_light_bake_mode);
  813.  
  814.     void _create_clips(Node *scene, const Array &p_clips, bool p_bake_all);
  815.     void _filter_anim_tracks(Ref<Animation> anim, Set<String> &keep);
  816. diff --git a/scene/main/node.h b/scene/main/node.h
  817. index 6f5544d..3017759 100644
  818. --- a/scene/main/node.h
  819. +++ b/scene/main/node.h
  820. @@ -46,6 +46,8 @@ class Node : public Object {
  821.     GDCLASS(Node, Object);
  822.     OBJ_CATEGORY("Nodes");
  823.  
  824. +   friend class ResourceImporterScene;
  825. +
  826.  public:
  827.     enum PauseMode {
Add Comment
Please, Sign In to add comment