Clean up ASSIMP import code.
This commit is contained in:
parent
89efaf5e78
commit
ad1368a625
5 changed files with 1177 additions and 1511 deletions
File diff suppressed because it is too large
Load diff
|
@ -146,37 +146,65 @@ private:
|
|||
COORD_LEFT = 1
|
||||
};
|
||||
};
|
||||
Spatial *_generate_scene(const String &p_path, const aiScene *scene, const uint32_t p_flags, int p_bake_fps, const int32_t p_max_bone_weights);
|
||||
void _fill_kept_node(Set<Node *> &keep_nodes);
|
||||
String _find_skeleton_bone_root(Map<Skeleton *, MeshInstance *> &skeletons, Map<MeshInstance *, String> &meshes, Spatial *root);
|
||||
void _set_bone_parent(Skeleton *s, Node *p_owner, aiNode *p_node);
|
||||
Transform _get_global_ai_node_transform(const aiScene *p_scene, const aiNode *p_current_node);
|
||||
void _generate_node_bone(const aiScene *p_scene, const aiNode *p_node, Map<String, bool> &p_mesh_bones, Skeleton *p_skeleton, const String p_path, const int32_t p_max_bone_weights);
|
||||
void _generate_node_bone_parents(const aiScene *p_scene, const aiNode *p_node, Map<String, bool> &p_mesh_bones, Skeleton *p_skeleton, const MeshInstance *p_mi);
|
||||
void _calculate_skeleton_root(Skeleton *s, const aiScene *p_scene, aiNode *&p_ai_skeleton_root, Map<String, bool> &mesh_bones, const aiNode *p_node);
|
||||
void _fill_skeleton(const aiScene *p_scene, const aiNode *p_node, Spatial *p_current, Node *p_owner, Skeleton *p_skeleton, const Map<String, bool> p_mesh_bones, const Map<String, Transform> &p_bone_rests, Set<String> p_tracks, const String p_path, Set<String> &r_removed_bones);
|
||||
void _keep_node(const String &p_path, Node *p_current, Node *p_owner, Set<Node *> &r_keep_nodes);
|
||||
void _filter_node(const String &p_path, Node *p_current, Node *p_owner, const Set<Node *> p_keep_nodes, Set<String> &r_removed_nodes);
|
||||
void _generate_node(const String &p_path, const aiScene *p_scene, const aiNode *p_node, Node *p_parent, Node *p_owner, Set<String> &r_bone_name, Set<String> p_light_names, Set<String> p_camera_names, Map<Skeleton *, MeshInstance *> &r_skeletons, const Map<String, Transform> &p_bone_rests, Vector<MeshInstance *> &r_mesh_instances, int32_t &r_mesh_count, Skeleton *p_skeleton, const int32_t p_max_bone_weights, Set<String> &r_removed_bones, Map<String, Map<uint32_t, String> > &r_name_morph_mesh_names);
|
||||
aiNode *_ai_find_node(aiNode *ai_child_node, const String bone_name);
|
||||
Transform _format_rot_xform(const String p_path, const aiScene *p_scene);
|
||||
void _get_track_set(const aiScene *p_scene, Set<String> &tracks);
|
||||
void _insert_animation_track(const aiScene *p_scene, const String p_path, int p_bake_fps, Ref<Animation> animation, float ticks_per_second, float length, const Skeleton *sk, const aiNodeAnim *track, String node_name, NodePath node_path);
|
||||
void _add_mesh_to_mesh_instance(const aiNode *p_node, const aiScene *p_scene, Skeleton *s, const String &p_path, MeshInstance *p_mesh_instance, Node *p_owner, Set<String> &r_bone_name, int32_t &r_mesh_count, int32_t p_max_bone_weights, Map<String, Map<uint32_t, String> > &r_name_morph_mesh_names);
|
||||
Ref<Texture> _load_texture(const aiScene *p_scene, String p_path);
|
||||
|
||||
struct ImportState {
|
||||
|
||||
String path;
|
||||
const aiScene *assimp_scene;
|
||||
uint32_t max_bone_weights;
|
||||
Spatial *root;
|
||||
Map<String, Ref<Mesh> > mesh_cache;
|
||||
Map<int, Ref<Material> > material_cache;
|
||||
Map<String, int> light_cache;
|
||||
Map<String, int> camera_cache;
|
||||
Vector<Skeleton *> skeletons;
|
||||
Map<String, int> bone_owners; //maps bones to skeleton index owned by
|
||||
Map<String, Node *> node_map;
|
||||
Map<MeshInstance *, Skeleton *> mesh_skeletons;
|
||||
bool fbx; //for some reason assimp does some things different for FBX
|
||||
AnimationPlayer *animation_player;
|
||||
};
|
||||
|
||||
struct BoneInfo {
|
||||
uint32_t bone;
|
||||
float weight;
|
||||
};
|
||||
|
||||
struct SkeletonHole { //nodes may be part of the skeleton by used by vertex
|
||||
String name;
|
||||
String parent;
|
||||
Transform pose;
|
||||
const aiNode *node;
|
||||
};
|
||||
|
||||
const Transform _assimp_matrix_transform(const aiMatrix4x4 p_matrix);
|
||||
String _assimp_get_string(const aiString p_string) const;
|
||||
Transform _get_global_assimp_node_transform(const aiNode *p_current_node);
|
||||
|
||||
void _calc_tangent_from_mesh(const aiMesh *ai_mesh, int i, int tri_index, int index, PoolColorArray::Write &w);
|
||||
void _set_texture_mapping_mode(aiTextureMapMode *map_mode, Ref<Texture> texture);
|
||||
void _find_texture_path(const String &p_path, String &path, bool &r_found);
|
||||
void _find_texture_path(const String &p_path, _Directory &dir, String &path, bool &found, String extension);
|
||||
String _ai_string_to_string(const aiString p_string) const;
|
||||
String _ai_anim_string_to_string(const aiString p_string) const;
|
||||
String _ai_raw_string_to_string(const aiString p_string) const;
|
||||
void _import_animation(const String p_path, const Vector<MeshInstance *> p_meshes, const aiScene *p_scene, AnimationPlayer *ap, int32_t p_index, int p_bake_fps, Map<Skeleton *, MeshInstance *> p_skeletons, const Set<String> p_removed_nodes, const Set<String> removed_bones, const Map<String, Map<uint32_t, String> > p_path_morph_mesh_names);
|
||||
void _insert_pivot_anim_track(const Vector<MeshInstance *> p_meshes, const String p_node_name, Vector<const aiNodeAnim *> F, AnimationPlayer *ap, Skeleton *sk, float &length, float ticks_per_second, Ref<Animation> animation, int p_bake_fps, const String &p_path, const aiScene *p_scene);
|
||||
|
||||
Ref<Texture> _load_texture(ImportState &state, String p_path);
|
||||
Ref<Material> _generate_material_from_index(ImportState &state, int p_index, bool p_double_sided);
|
||||
Ref<Mesh> _generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices, Skeleton *p_skeleton = NULL, bool p_double_sided_material = false);
|
||||
void _generate_node(ImportState &state, const aiNode *p_assimp_node, Node *p_parent);
|
||||
void _generate_bone_groups(ImportState &state, const aiNode *p_assimp_node, Map<String, int> &ownership, Map<String, Transform> &bind_xforms);
|
||||
void _fill_node_relationships(ImportState &state, const aiNode *p_assimp_node, Map<String, int> &ownership, Map<int, int> &skeleton_map, int p_skeleton_id, Skeleton *p_skeleton, const String &p_parent_name, int &holecount, const Vector<SkeletonHole> &p_holes, const Map<String, Transform> &bind_xforms);
|
||||
void _generate_skeletons(ImportState &state, const aiNode *p_assimp_node, Map<String, int> &ownership, Map<int, int> &skeleton_map, const Map<String, Transform> &bind_xforms);
|
||||
|
||||
void _insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int p_track, int p_bake_fps, Ref<Animation> animation, float ticks_per_second, Skeleton *p_skeleton, const NodePath &p_path, const String &p_name);
|
||||
|
||||
void _import_animation(ImportState &state, int p_animation_index, int p_bake_fps);
|
||||
|
||||
Spatial *_generate_scene(const String &p_path, const aiScene *scene, const uint32_t p_flags, int p_bake_fps, const int32_t p_max_bone_weights);
|
||||
|
||||
String _assimp_anim_string_to_string(const aiString p_string) const;
|
||||
String _assimp_raw_string_to_string(const aiString p_string) const;
|
||||
float _get_fbx_fps(int32_t time_mode, const aiScene *p_scene);
|
||||
template <class T>
|
||||
T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp);
|
||||
const Transform _ai_matrix_transform(const aiMatrix4x4 p_matrix);
|
||||
void _register_project_setting_import(const String generic, const String import_setting_string, const Vector<String> &exts, List<String> *r_extensions, const bool p_enabled) const;
|
||||
|
||||
struct ImportFormat {
|
||||
|
|
|
@ -540,10 +540,11 @@ void Skeleton::clear_bones() {
|
|||
void Skeleton::set_bone_pose(int p_bone, const Transform &p_pose) {
|
||||
|
||||
ERR_FAIL_INDEX(p_bone, bones.size());
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
|
||||
bones.write[p_bone].pose = p_pose;
|
||||
_make_dirty();
|
||||
if (is_inside_tree()) {
|
||||
_make_dirty();
|
||||
}
|
||||
}
|
||||
Transform Skeleton::get_bone_pose(int p_bone) const {
|
||||
|
||||
|
|
|
@ -108,8 +108,55 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) {
|
|||
vtx.bones = last_bones;
|
||||
vtx.tangent = last_tangent.normal;
|
||||
vtx.binormal = last_normal.cross(last_tangent.normal).normalized() * last_tangent.d;
|
||||
|
||||
const int expected_vertices = 4;
|
||||
|
||||
if ((format & Mesh::ARRAY_FORMAT_WEIGHTS || format & Mesh::ARRAY_FORMAT_BONES) && (vtx.weights.size() != expected_vertices || vtx.bones.size() != expected_vertices)) {
|
||||
//ensure vertices are the expected amount
|
||||
ERR_FAIL_COND(vtx.weights.size() != vtx.bones.size());
|
||||
if (vtx.weights.size() < expected_vertices) {
|
||||
//less than requred, fill
|
||||
for (int i = vtx.weights.size(); i < expected_vertices; i++) {
|
||||
vtx.weights.push_back(0);
|
||||
vtx.bones.push_back(0);
|
||||
}
|
||||
} else if (vtx.weights.size() > expected_vertices) {
|
||||
//more than required, sort, cap and normalize.
|
||||
Vector<WeightSort> weights;
|
||||
for (int i = 0; i < vtx.weights.size(); i++) {
|
||||
WeightSort ws;
|
||||
ws.index = vtx.bones[i];
|
||||
ws.weight = vtx.weights[i];
|
||||
weights.push_back(ws);
|
||||
}
|
||||
|
||||
//sort
|
||||
weights.sort();
|
||||
//cap
|
||||
weights.resize(expected_vertices);
|
||||
//renormalize
|
||||
float total = 0;
|
||||
for (int i = 0; i < expected_vertices; i++) {
|
||||
total += weights[i].weight;
|
||||
}
|
||||
|
||||
vtx.weights.resize(expected_vertices);
|
||||
vtx.bones.resize(expected_vertices);
|
||||
|
||||
for (int i = 0; i < expected_vertices; i++) {
|
||||
if (total > 0) {
|
||||
vtx.weights.write[i] = weights[i].weight / total;
|
||||
} else {
|
||||
vtx.weights.write[i] = 0;
|
||||
}
|
||||
vtx.bones.write[i] = weights[i].index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vertex_array.push_back(vtx);
|
||||
first = false;
|
||||
|
||||
format |= Mesh::ARRAY_FORMAT_VERTEX;
|
||||
}
|
||||
void SurfaceTool::add_color(Color p_color) {
|
||||
|
@ -161,7 +208,6 @@ void SurfaceTool::add_uv2(const Vector2 &p_uv2) {
|
|||
void SurfaceTool::add_bones(const Vector<int> &p_bones) {
|
||||
|
||||
ERR_FAIL_COND(!begun);
|
||||
ERR_FAIL_COND(p_bones.size() != 4);
|
||||
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_BONES));
|
||||
|
||||
format |= Mesh::ARRAY_FORMAT_BONES;
|
||||
|
@ -171,8 +217,6 @@ void SurfaceTool::add_bones(const Vector<int> &p_bones) {
|
|||
void SurfaceTool::add_weights(const Vector<float> &p_weights) {
|
||||
|
||||
ERR_FAIL_COND(!begun);
|
||||
|
||||
ERR_FAIL_COND(p_weights.size() != 4);
|
||||
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_WEIGHTS));
|
||||
|
||||
format |= Mesh::ARRAY_FORMAT_WEIGHTS;
|
||||
|
|
|
@ -62,6 +62,14 @@ private:
|
|||
static _FORCE_INLINE_ uint32_t hash(const Vertex &p_vtx);
|
||||
};
|
||||
|
||||
struct WeightSort {
|
||||
int index;
|
||||
float weight;
|
||||
bool operator<(const WeightSort &p_right) const {
|
||||
return weight < p_right.weight;
|
||||
}
|
||||
};
|
||||
|
||||
bool begun;
|
||||
bool first;
|
||||
Mesh::PrimitiveType primitive;
|
||||
|
|
Loading…
Reference in a new issue