fbx_mesh_data.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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 "core/templates/local_vector.h"
  34. #include "core/templates/ordered_hash_map.h"
  35. #include "editor/import/resource_importer_scene.h"
  36. #include "editor/import/scene_importer_mesh_node_3d.h"
  37. #include "scene/3d/mesh_instance_3d.h"
  38. #include "scene/resources/surface_tool.h"
  39. #include "fbx_bone.h"
  40. #include "fbx_parser/FBXMeshGeometry.h"
  41. #include "import_state.h"
  42. #include "tools/import_utils.h"
  43. struct FBXNode;
  44. struct FBXMeshData;
  45. struct FBXBone;
  46. struct ImportState;
  47. typedef int Vertex;
  48. typedef int SurfaceId;
  49. typedef int PolygonId;
  50. typedef int DataIndex;
  51. struct SurfaceData {
  52. Ref<SurfaceTool> surface_tool;
  53. OrderedHashMap<Vertex, int> lookup_table; // proposed fix is to replace lookup_table[vertex_id] to give the position of the vertices_map[int] index.
  54. LocalVector<Vertex> vertices_map; // this must be ordered the same as insertion <-- slow to do find() operation.
  55. Ref<Material> material;
  56. HashMap<PolygonId, Vector<DataIndex>> surface_polygon_vertex;
  57. Array morphs;
  58. };
  59. struct VertexWeightMapping {
  60. Vector<real_t> weights;
  61. Vector<int> bones;
  62. // This extra vector is used because the bone id is computed in a second step.
  63. // TODO Get rid of this extra step is a good idea.
  64. Vector<Ref<FBXBone>> bones_ref;
  65. };
  66. template <class T>
  67. struct VertexData {
  68. int polygon_index;
  69. T data;
  70. };
  71. // Caches mesh information and instantiates meshes for you using helper functions.
  72. struct FBXMeshData : Reference {
  73. struct MorphVertexData {
  74. // TODO we have only these??
  75. /// Each element is a vertex. Not supposed to be void.
  76. Vector<Vector3> vertices;
  77. /// Each element is a vertex. Not supposed to be void.
  78. Vector<Vector3> normals;
  79. };
  80. // FIXME: remove this is a hack for testing only
  81. mutable const FBXDocParser::MeshGeometry *mesh_geometry = nullptr;
  82. Ref<FBXNode> mesh_node = nullptr;
  83. /// vertex id, Weight Info
  84. /// later: perf we can use array here
  85. HashMap<int, VertexWeightMapping> vertex_weights;
  86. // translate fbx mesh data from document context to FBX Mesh Geometry Context
  87. bool valid_weight_indexes = false;
  88. EditorSceneImporterMeshNode3D *create_fbx_mesh(const ImportState &state, const FBXDocParser::MeshGeometry *p_mesh_geometry, const FBXDocParser::Model *model, bool use_compression);
  89. void gen_weight_info(Ref<SurfaceTool> st, int vertex_id) const;
  90. /* mesh maximum weight count */
  91. bool valid_weight_count = false;
  92. int max_weight_count = 0;
  93. uint64_t armature_id = 0;
  94. bool valid_armature_id = false;
  95. EditorSceneImporterMeshNode3D *godot_mesh_instance = nullptr;
  96. private:
  97. void sanitize_vertex_weights(const ImportState &state);
  98. /// Make sure to reorganize the vertices so that the correct UV is taken.
  99. /// This step is needed because differently from the normal, that can be
  100. /// combined, the UV may need its own triangle because sometimes they have
  101. /// really different UV for the same vertex but different polygon.
  102. /// This function make sure to add another vertex for those UVS.
  103. void reorganize_vertices(
  104. std::vector<int> &r_polygon_indices,
  105. std::vector<Vector3> &r_vertices,
  106. HashMap<int, Vector3> &r_normals,
  107. HashMap<int, Vector2> &r_uv_1,
  108. HashMap<int, Vector2> &r_uv_2,
  109. HashMap<int, Color> &r_color,
  110. HashMap<String, MorphVertexData> &r_morphs,
  111. HashMap<int, HashMap<int, Vector3>> &r_normals_raw,
  112. HashMap<int, HashMap<int, Color>> &r_colors_raw,
  113. HashMap<int, HashMap<int, Vector2>> &r_uv_1_raw,
  114. HashMap<int, HashMap<int, Vector2>> &r_uv_2_raw);
  115. void add_vertex(
  116. const ImportState &state,
  117. Ref<SurfaceTool> p_surface_tool,
  118. real_t p_scale,
  119. int p_vertex,
  120. const std::vector<Vector3> &p_vertices_position,
  121. const HashMap<int, Vector3> &p_normals,
  122. const HashMap<int, Vector2> &p_uvs_0,
  123. const HashMap<int, Vector2> &p_uvs_1,
  124. const HashMap<int, Color> &p_colors,
  125. const Vector3 &p_morph_value = Vector3(),
  126. const Vector3 &p_morph_normal = Vector3());
  127. void triangulate_polygon(SurfaceData *surface, const Vector<int> &p_polygon_vertex, const std::vector<Vector3> &p_vertices) const;
  128. /// This function is responsible to convert the FBX polygon vertex to
  129. /// vertex index.
  130. /// The polygon vertices are stored in an array with some negative
  131. /// values. The negative values define the last face index.
  132. /// For example the following `face_array` contains two faces, the former
  133. /// with 3 vertices and the latter with a line:
  134. /// [0,2,-2,3,-5]
  135. /// Parsed as:
  136. /// [0, 2, 1, 3, 4]
  137. /// The negative values are computed using this formula: `(-value) - 1`
  138. ///
  139. /// Returns the vertex index from the poligon vertex.
  140. /// Returns -1 if `p_index` is invalid.
  141. int get_vertex_from_polygon_vertex(const std::vector<int> &p_face_indices, int p_index) const;
  142. /// Returns true if this polygon_vertex_index is the end of a new polygon.
  143. bool is_end_of_polygon(const std::vector<int> &p_face_indices, int p_index) const;
  144. /// Returns true if this polygon_vertex_index is the begin of a new polygon.
  145. bool is_start_of_polygon(const std::vector<int> &p_face_indices, int p_index) const;
  146. /// Returns the number of polygons.
  147. int count_polygons(const std::vector<int> &p_face_indices) const;
  148. /// Used to extract data from the `MappingData` aligned with vertex.
  149. /// Useful to extract normal/uvs/colors/tangents/etc...
  150. /// If the function fails somehow, it returns an hollow vector and print an error.
  151. template <class R, class T>
  152. HashMap<int, R> extract_per_vertex_data(
  153. int p_vertex_count,
  154. const std::vector<FBXDocParser::MeshGeometry::Edge> &p_edges,
  155. const std::vector<int> &p_mesh_indices,
  156. const FBXDocParser::MeshGeometry::MappingData<T> &p_mapping_data,
  157. R (*collector_function)(const Vector<VertexData<T>> *p_vertex_data, R p_fall_back),
  158. R p_fall_back) const;
  159. /// Used to extract data from the `MappingData` organized per polygon.
  160. /// Useful to extract the material
  161. /// If the function fails somehow, it returns an hollow vector and print an error.
  162. template <class T>
  163. HashMap<int, T> extract_per_polygon(
  164. int p_vertex_count,
  165. const std::vector<int> &p_face_indices,
  166. const FBXDocParser::MeshGeometry::MappingData<T> &p_fbx_data,
  167. T p_fallback_value) const;
  168. /// Extracts the morph data and organizes it per vertices.
  169. /// The returned `MorphVertexData` arrays are never something different
  170. /// then the `vertex_count`.
  171. void extract_morphs(const FBXDocParser::MeshGeometry *mesh_geometry, HashMap<String, MorphVertexData> &r_data);
  172. };
  173. #endif // FBX_MESH_DATA_H