fbx_mesh_data.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*************************************************************************/
  2. /* fbx_mesh_data.h */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #ifndef FBX_MESH_DATA_H
  31. #define FBX_MESH_DATA_H
  32. #include "core/templates/hash_map.h"
  33. #include "editor/import/resource_importer_scene.h"
  34. #include "editor/import/scene_importer_mesh_node_3d.h"
  35. #include "scene/3d/mesh_instance_3d.h"
  36. #include "scene/resources/surface_tool.h"
  37. #include "fbx_bone.h"
  38. #include "fbx_parser/FBXMeshGeometry.h"
  39. #include "import_state.h"
  40. #include "tools/import_utils.h"
  41. struct FBXNode;
  42. struct FBXMeshData;
  43. struct FBXBone;
  44. struct ImportState;
  45. struct VertexWeightMapping {
  46. Vector<real_t> weights;
  47. Vector<int> bones;
  48. // This extra vector is used because the bone id is computed in a second step.
  49. // TODO Get rid of this extra step is a good idea.
  50. Vector<Ref<FBXBone>> bones_ref;
  51. };
  52. template <class T>
  53. struct VertexData {
  54. int polygon_index;
  55. T data;
  56. };
  57. // Caches mesh information and instantiates meshes for you using helper functions.
  58. struct FBXMeshData : Reference {
  59. struct MorphVertexData {
  60. // TODO we have only these??
  61. /// Each element is a vertex. Not supposed to be void.
  62. Vector<Vector3> vertices;
  63. /// Each element is a vertex. Not supposed to be void.
  64. Vector<Vector3> normals;
  65. };
  66. // FIXME: remove this is a hack for testing only
  67. mutable const FBXDocParser::MeshGeometry *mesh_geometry = nullptr;
  68. Ref<FBXNode> mesh_node = nullptr;
  69. /// vertex id, Weight Info
  70. /// later: perf we can use array here
  71. HashMap<int, VertexWeightMapping> vertex_weights;
  72. // translate fbx mesh data from document context to FBX Mesh Geometry Context
  73. bool valid_weight_indexes = false;
  74. EditorSceneImporterMeshNode3D *create_fbx_mesh(const ImportState &state, const FBXDocParser::MeshGeometry *p_mesh_geometry, const FBXDocParser::Model *model, bool use_compression);
  75. void gen_weight_info(Ref<SurfaceTool> st, int vertex_id) const;
  76. /* mesh maximum weight count */
  77. bool valid_weight_count = false;
  78. int max_weight_count = 0;
  79. uint64_t armature_id = 0;
  80. bool valid_armature_id = false;
  81. EditorSceneImporterMeshNode3D *godot_mesh_instance = nullptr;
  82. private:
  83. void sanitize_vertex_weights(const ImportState &state);
  84. /// Make sure to reorganize the vertices so that the correct UV is taken.
  85. /// This step is needed because differently from the normal, that can be
  86. /// combined, the UV may need its own triangle because sometimes they have
  87. /// really different UV for the same vertex but different polygon.
  88. /// This function make sure to add another vertex for those UVS.
  89. void reorganize_vertices(
  90. std::vector<int> &r_polygon_indices,
  91. std::vector<Vector3> &r_vertices,
  92. HashMap<int, Vector3> &r_normals,
  93. HashMap<int, Vector2> &r_uv_1,
  94. HashMap<int, Vector2> &r_uv_2,
  95. HashMap<int, Color> &r_color,
  96. HashMap<String, MorphVertexData> &r_morphs,
  97. HashMap<int, HashMap<int, Vector3>> &r_normals_raw,
  98. HashMap<int, HashMap<int, Color>> &r_colors_raw,
  99. HashMap<int, HashMap<int, Vector2>> &r_uv_1_raw,
  100. HashMap<int, HashMap<int, Vector2>> &r_uv_2_raw);
  101. void add_vertex(
  102. const ImportState &state,
  103. Ref<SurfaceTool> p_surface_tool,
  104. real_t p_scale,
  105. int p_vertex,
  106. const std::vector<Vector3> &p_vertices_position,
  107. const HashMap<int, Vector3> &p_normals,
  108. const HashMap<int, Vector2> &p_uvs_0,
  109. const HashMap<int, Vector2> &p_uvs_1,
  110. const HashMap<int, Color> &p_colors,
  111. const Vector3 &p_morph_value = Vector3(),
  112. const Vector3 &p_morph_normal = Vector3());
  113. void triangulate_polygon(Ref<SurfaceTool> st, Vector<int> p_polygon_vertex, Vector<int> p_surface_vertex_map, const std::vector<Vector3> &p_vertices) const;
  114. /// This function is responsible to convert the FBX polygon vertex to
  115. /// vertex index.
  116. /// The polygon vertices are stored in an array with some negative
  117. /// values. The negative values define the last face index.
  118. /// For example the following `face_array` contains two faces, the former
  119. /// with 3 vertices and the latter with a line:
  120. /// [0,2,-2,3,-5]
  121. /// Parsed as:
  122. /// [0, 2, 1, 3, 4]
  123. /// The negative values are computed using this formula: `(-value) - 1`
  124. ///
  125. /// Returns the vertex index from the poligon vertex.
  126. /// Returns -1 if `p_index` is invalid.
  127. int get_vertex_from_polygon_vertex(const std::vector<int> &p_face_indices, int p_index) const;
  128. /// Returns true if this polygon_vertex_index is the end of a new polygon.
  129. bool is_end_of_polygon(const std::vector<int> &p_face_indices, int p_index) const;
  130. /// Returns true if this polygon_vertex_index is the begin of a new polygon.
  131. bool is_start_of_polygon(const std::vector<int> &p_face_indices, int p_index) const;
  132. /// Returns the number of polygons.
  133. int count_polygons(const std::vector<int> &p_face_indices) const;
  134. /// Used to extract data from the `MappingData` aligned with vertex.
  135. /// Useful to extract normal/uvs/colors/tangents/etc...
  136. /// If the function fails somehow, it returns an hollow vector and print an error.
  137. template <class R, class T>
  138. HashMap<int, R> extract_per_vertex_data(
  139. int p_vertex_count,
  140. const std::vector<FBXDocParser::MeshGeometry::Edge> &p_edges,
  141. const std::vector<int> &p_mesh_indices,
  142. const FBXDocParser::MeshGeometry::MappingData<T> &p_mapping_data,
  143. R (*collector_function)(const Vector<VertexData<T>> *p_vertex_data, R p_fall_back),
  144. R p_fall_back) const;
  145. /// Used to extract data from the `MappingData` organized per polygon.
  146. /// Useful to extract the material
  147. /// If the function fails somehow, it returns an hollow vector and print an error.
  148. template <class T>
  149. HashMap<int, T> extract_per_polygon(
  150. int p_vertex_count,
  151. const std::vector<int> &p_face_indices,
  152. const FBXDocParser::MeshGeometry::MappingData<T> &p_fbx_data,
  153. T p_fallback_value) const;
  154. /// Extracts the morph data and organizes it per vertices.
  155. /// The returned `MorphVertexData` arrays are never something different
  156. /// then the `vertex_count`.
  157. void extract_morphs(const FBXDocParser::MeshGeometry *mesh_geometry, HashMap<String, MorphVertexData> &r_data);
  158. };
  159. #endif // FBX_MESH_DATA_H