void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) { Node *parent = get_node(root); ERR_FAIL_COND(!parent); Animation *a=p_anim->animation.operator->(); p_anim->node_cache.resize( a->get_track_count() ); for (int i=0;i<a->get_track_count();i++) { p_anim->node_cache[i]=NULL; RES resource; Node *child = parent->get_node_and_resource(a->track_get_path(i),resource); if (!child) { ERR_EXPLAIN("On Animation: '"+p_anim->name+"', couldn't resolve track: '"+String(a->track_get_path(i))+"'"); } ERR_CONTINUE(!child); // couldn't find the child node uint32_t id=resource.is_valid()?resource->get_instance_ID():child->get_instance_ID(); int bone_idx=-1; if (a->track_get_path(i).get_property() && child->cast_to<Skeleton>()) { bone_idx = child->cast_to<Skeleton>()->find_bone( a->track_get_path(i).get_property() ); if (bone_idx==-1) { continue; } } { if (!child->is_connected("exit_tree",this,"_node_removed")) child->connect("exit_tree",this,"_node_removed",make_binds(child),CONNECT_ONESHOT); } TrackNodeCacheKey key; key.id=id; key.bone_idx=bone_idx; if (node_cache_map.has(key)) { p_anim->node_cache[i]=&node_cache_map[key]; } else { node_cache_map[key]=TrackNodeCache(); p_anim->node_cache[i]=&node_cache_map[key]; p_anim->node_cache[i]->path=a->track_get_path(i); p_anim->node_cache[i]->node=child; p_anim->node_cache[i]->resource=resource; p_anim->node_cache[i]->node_2d=child->cast_to<Node2D>(); if (a->track_get_type(i)==Animation::TYPE_TRANSFORM) { // special cases and caches for transform tracks // cache spatial p_anim->node_cache[i]->spatial=child->cast_to<Spatial>(); // cache skeleton p_anim->node_cache[i]->skeleton=child->cast_to<Skeleton>(); if (p_anim->node_cache[i]->skeleton) { StringName bone_name=a->track_get_path(i).get_property(); if (bone_name.operator String()!="") { p_anim->node_cache[i]->bone_idx=p_anim->node_cache[i]->skeleton->find_bone(bone_name); if (p_anim->node_cache[i]->bone_idx<0) { // broken track (nonexistent bone) p_anim->node_cache[i]->skeleton=NULL; p_anim->node_cache[i]->spatial=NULL; printf("bone is %ls\n", String(bone_name).c_str()); ERR_CONTINUE( p_anim->node_cache[i]->bone_idx<0 ); } else { } } else { // no property, just use spatialnode p_anim->node_cache[i]->skeleton=NULL; } } } } if (a->track_get_type(i)==Animation::TYPE_VALUE) { StringName property = a->track_get_path(i).get_property(); if (!p_anim->node_cache[i]->property_anim.has(property)) { TrackNodeCache::PropertyAnim pa; pa.prop=property; pa.object=resource.is_valid()?(Object*)resource.ptr():(Object*)child; pa.special=SP_NONE; pa.owner=p_anim->node_cache[i]; if (false && p_anim->node_cache[i]->node_2d) { if (pa.prop==SceneStringNames::get_singleton()->transform_pos) pa.special=SP_NODE2D_POS; else if (pa.prop==SceneStringNames::get_singleton()->transform_rot) pa.special=SP_NODE2D_ROT; else if (pa.prop==SceneStringNames::get_singleton()->transform_scale) pa.special=SP_NODE2D_SCALE; } p_anim->node_cache[i]->property_anim[property]=pa; } } } }