Skip to content

Commit

Permalink
Merge pull request #2460 from KhronosGroup/fix_b133164
Browse files Browse the repository at this point in the history
Change id_root to target_id_type
  • Loading branch information
julienduroure authored Jan 21, 2025
2 parents 2fc08d3 + 9b6f0e4 commit 9b3176b
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 42 deletions.
42 changes: 21 additions & 21 deletions addons/io_scene_gltf2/blender/exp/animation/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def add_action(self, action):
self.actions[id(action.action)] = action
else:
for slot in action.slots:
self.actions[id(action.action)].add_slot(slot.slot, slot.id_root, slot.track)
self.actions[id(action.action)].add_slot(slot.slot, slot.target_id_type, slot.track)

def get(self):
# sort animations alphabetically (case insensitive) so they have a defined order and match Blender's Action list
Expand Down Expand Up @@ -80,28 +80,28 @@ def __init__(self, action):
self.action = action
self.slots = []

def add_slot(self, slot, id_root, track):
def add_slot(self, slot, target_id_type, track):
# If slot already exists with None track (so active action/slot) => Replace it with the track (NLA)
f = [s for s in self.slots if s.slot.handle == slot.handle and s.track is None]
if len(f) > 0:
self.slots.remove(f[0])
new_slot = SlotData(slot, id_root, track)
new_slot = SlotData(slot, target_id_type, track)
self.slots.append(new_slot)

def sort(self):
# Implement sorting, to be sure to get:
# TRS first, and then SK
sort_items = {'OBJECT': 1, 'KEY': 2}
self.slots.sort(key=lambda x: sort_items.get(x.id_root))
self.slots.sort(key=lambda x: sort_items.get(x.target_id_type))

def has_slots(self):
return len(self.slots) > 0


class SlotData:
def __init__(self, slot, id_root, track):
def __init__(self, slot, target_id_type, track):
self.slot = slot
self.id_root = id_root
self.target_id_type = target_id_type
self.track = track


Expand Down Expand Up @@ -198,7 +198,7 @@ def prepare_actions_range(export_settings):
for action_data in blender_actions.values():
blender_action = action_data.action
for slot in action_data.slots:
type_ = slot.id_root
type_ = slot.target_id_type
track = slot.track

# Frame range is set on action level, not on slot level
Expand Down Expand Up @@ -455,7 +455,7 @@ def gather_action_animations(obj_uuid: int,
for slot in action_data.slots:
blender_action = action_data.action
track_name = slot.track
on_type = slot.id_root
on_type = slot.target_id_type

# Set action as active, to be able to bake if needed
if on_type == "OBJECT": # Not for shapekeys!
Expand Down Expand Up @@ -615,7 +615,7 @@ def gather_action_animations(obj_uuid: int,
all_channels)

# If we are in a SK animation (without any TRS animation), and we need to bake
if len([a for a in blender_actions.values() if len([s for s in a.slots if s.id_root == "OBJECT"]) != 0]) == 0 and slot.id_root == "KEY":
if len([a for a in blender_actions.values() if len([s for s in a.slots if s.target_id_type == "OBJECT"]) != 0]) == 0 and slot.target_id_type == "KEY":
if export_settings['gltf_bake_animation'] is True and export_settings['gltf_force_sampling'] is True:
# We also have to check if this is a skinned mesh, because we don't have to force animation baking on this case
# (skinned meshes TRS must be ignored, says glTF specification)
Expand All @@ -628,7 +628,7 @@ def gather_action_animations(obj_uuid: int,
if channels is not None:
all_channels.extend(channels)

if len([a for a in blender_actions.values() if len([s for s in a.slots if s.id_root == "KEY"]) != 0]) == 0 \
if len([a for a in blender_actions.values() if len([s for s in a.slots if s.target_id_type == "KEY"]) != 0]) == 0 \
and export_settings['gltf_morph_anim'] \
and blender_object.type == "MESH" \
and blender_object.data is not None \
Expand Down Expand Up @@ -769,7 +769,7 @@ def __get_blender_actions(obj_uuid: str,
else:
# Store Action info
new_action = ActionData(blender_object.animation_data.action)
new_action.add_slot(blender_object.animation_data.action_slot, blender_object.animation_data.action_slot.id_root, None) # Active action => No track
new_action.add_slot(blender_object.animation_data.action_slot, blender_object.animation_data.action_slot.target_id_type, None) # Active action => No track
actions.add_action(new_action)

# Collect associated strips from NLA tracks.
Expand All @@ -795,7 +795,7 @@ def __get_blender_actions(obj_uuid: str,

# Store Action info
new_action = ActionData(strip.action)
new_action.add_slot(strip.action_slot, strip.action_slot.id_root, track.name)
new_action.add_slot(strip.action_slot, strip.action_slot.target_id_type, track.name)
actions.add_action(new_action)

# For caching, actions linked to SK must be after actions about TRS
Expand All @@ -813,7 +813,7 @@ def __get_blender_actions(obj_uuid: str,
else:
# Store Action info
new_action = ActionData(blender_object.data.shape_keys.animation_data.action)
new_action.add_slot(blender_object.data.shape_keys.animation_data.action_slot, blender_object.data.shape_keys.animation_data.action_slot.id_root, None)
new_action.add_slot(blender_object.data.shape_keys.animation_data.action_slot, blender_object.data.shape_keys.animation_data.action_slot.target_id_type, None)
actions.add_action(new_action)

if export_settings['gltf_animation_mode'] == "ACTIONS":
Expand All @@ -831,7 +831,7 @@ def __get_blender_actions(obj_uuid: str,

# Store Action info
new_action = ActionData(strip.action)
new_action.add_slot(strip.action_slot, strip.action_slot.id_root, track.name)
new_action.add_slot(strip.action_slot, strip.action_slot.target_id_type, track.name)
actions.add_action(new_action)

# If there are only 1 armature, include all animations, even if not in NLA
Expand All @@ -842,7 +842,7 @@ def __get_blender_actions(obj_uuid: str,
if len(export_settings['vtree'].get_all_node_of_type(VExportNode.ARMATURE)) == 1:
# Keep all actions on objects (no Shapekey animation)
for act in bpy.data.actions:
for slot in [s for s in act.slots if s.id_root == "OBJECT"]:
for slot in [s for s in act.slots if s.target_id_type == "OBJECT"]:
# We need to check this is an armature action
# Checking that at least 1 bone is animated
if not __is_armature_slot(act, slot):
Expand All @@ -857,7 +857,7 @@ def __get_blender_actions(obj_uuid: str,
continue # We ignore this action

new_action = ActionData(act)
new_action.add_slot(slot, slot.id_root, None)
new_action.add_slot(slot, slot.target_id_type, None)
actions.add_action(new_action)

export_user_extensions('gather_actions_hook', export_settings, blender_object, actions)
Expand Down Expand Up @@ -907,26 +907,26 @@ def __get_blender_actions_broadcast(obj_uuid, export_settings):

for slot in blender_action.slots:

if slot.id_root == "OBJECT":
if slot.target_id_type == "OBJECT":

# Do not export actions on objects without animation data
if blender_object.animation_data is None:
continue

if blender_object and blender_object.type == "ARMATURE" and __is_armature_slot(blender_action, slot):
new_action.add_slot(slot, slot.id_root, None)
new_action.add_slot(slot, slot.target_id_type, None)
elif blender_object and blender_object.type == "MESH" and not __is_armature_slot(blender_action, slot):
new_action.add_slot(slot, slot.id_root, None)
new_action.add_slot(slot, slot.target_id_type, None)

elif slot.id_root == "KEY":
elif slot.target_id_type == "KEY":
if blender_object.type != "MESH" or blender_object.data is None or blender_object.data.shape_keys is None or blender_object.data.shape_keys.animation_data is None:
continue
# Checking that the object has some SK and some animation on it
if blender_object is None:
continue
if blender_object.type != "MESH":
continue
new_action.add_slot(slot, slot.id_root, None)
new_action.add_slot(slot, slot.target_id_type, None)

else:
pass # TODOSLOT slot-3
Expand Down
2 changes: 1 addition & 1 deletion addons/io_scene_gltf2/blender/exp/animation/anim_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def reset_sk_data(blender_object, datas, export_settings) -> None:
return
else:
# For actions
if len([i for i in datas.values() if len([s for s in i.slots if s.id_root == "KEY"]) != 0]) <= 1:
if len([i for i in datas.values() if len([s for s in i.slots if s.target_id_type == "KEY"]) != 0]) <= 1:
return

if blender_object.type != "MESH":
Expand Down
2 changes: 1 addition & 1 deletion addons/io_scene_gltf2/blender/imp/animation.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def anim(gltf, anim_idx):
# Caches the action/slot for each object, keyed by:
# - anim_idx
# - obj_name
# - id_root
# - target_id_type
gltf.action_cache = {}
# Things we need to stash when we're done.
gltf.needs_stash = []
Expand Down
32 changes: 16 additions & 16 deletions addons/io_scene_gltf2/blender/imp/animation_pointer.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,20 @@ def do_channel(gltf, anim_idx, channel, asset, asset_idx, asset_type, name=None,

import_user_extensions('gather_import_animation_pointer_channel_before_hook', gltf, animation, channel)

# For some asset_type, we need to check what is the real id_root
# For some asset_type, we need to check what is the real ID type.
if asset_type == "MATERIAL":
if len(pointer_tab) == 4 and pointer_tab[1] == "materials" and \
pointer_tab[3] == "alphaCutoff":
id_root = "MATERIAL"
target_id_type = "MATERIAL"
else:
id_root = "NODETREE"
target_id_type = "NODETREE"
elif asset_type == "MATERIAL_PBR":
id_root = "NODETREE"
target_id_type = "NODETREE"
else:
id_root = asset_type
target_id_type = asset_type

action, slot = BlenderPointerAnim.get_or_create_action_and_slot(
gltf, anim_idx, asset, asset_idx, id_root, name_=name)
gltf, anim_idx, asset, asset_idx, target_id_type, name_=name)

keys = BinaryData.get_data_from_accessor(gltf, animation.samplers[channel.sampler].input)
values = BinaryData.get_data_from_accessor(gltf, animation.samplers[channel.sampler].output)
Expand Down Expand Up @@ -730,27 +730,27 @@ def get_or_create_action_and_slot(gltf, anim_idx, asset, asset_idx, asset_type,
if asset_type == "CAMERA":
name = asset.name
stash = asset.blender_object_data
id_root = "CAMERA"
target_id_type = "CAMERA"
elif asset_type == "LIGHT":
name = asset['name']
stash = asset['blender_object_data']
id_root = "LIGHT"
target_id_type = "LIGHT"
elif asset_type == "MATERIAL":
name = asset.name
stash = asset.blender_mat
id_root = "MATERIAL"
target_id_type = "MATERIAL"
elif asset_type == "NODETREE":
name = name_ if name_ is not None else asset.name
stash = asset.blender_nodetree
id_root = "NODETREE"
target_id_type = "NODETREE"
elif asset_type == "TEX_TRANSFORM":
name = name_ if name_ is not None else asset.name
stash = asset['blender_nodetree']
id_root = "NODETREE"
target_id_type = "NODETREE"
elif asset_type == "EXT":
name = name_ if name_ is not None else asset.name
stash = asset['blender_nodetree']
id_root = "NODETREE"
target_id_type = "NODETREE"

objects = gltf.action_cache.get(anim_idx)
if not objects:
Expand Down Expand Up @@ -778,18 +778,18 @@ def get_or_create_action_and_slot(gltf, anim_idx, asset, asset_idx, asset_type,
action.layers[0].strips[0].channelbags.new(slot)

gltf.action_cache[anim_idx]['object_slots'][name] = {}
gltf.action_cache[anim_idx]['object_slots'][name][slot.id_root] = (action, slot)
gltf.action_cache[anim_idx]['object_slots'][name][slot.target_id_type] = (action, slot)
else:
# We have slots, check if we have the right slot (based on id_root)
ac_sl = slots.get(id_root)
# We have slots, check if we have the right slot (based on target_id_type)
ac_sl = slots.get(target_id_type)
if not ac_sl:
action = gltf.action_cache[anim_idx]['action']
slot = action.slots.new(stash.id_type, "Slot")
gltf.needs_stash.append((stash, action, slot))

action.layers[0].strips[0].channelbags.new(slot)

gltf.action_cache[anim_idx]['object_slots'][name][slot.id_root] = (action, slot)
gltf.action_cache[anim_idx]['object_slots'][name][slot.target_id_type] = (action, slot)
else:
action, slot = ac_sl

Expand Down
6 changes: 3 additions & 3 deletions addons/io_scene_gltf2/blender/imp/animation_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ def get_or_create_action_and_slot(gltf, vnode_idx, anim_idx, path):
action.layers[0].strips[0].channelbags.new(slot)

gltf.action_cache[anim_idx]['object_slots'][obj.name] = {}
gltf.action_cache[anim_idx]['object_slots'][obj.name][slot.id_root] = (action, slot)
gltf.action_cache[anim_idx]['object_slots'][obj.name][slot.target_id_type] = (action, slot)
else:
# We have slots, check if we have the right slot (based on id_root)
# We have slots, check if we have the right slot (based on target_id_type)
ac_sl = slots.get(use_id)
if not ac_sl:
action = gltf.action_cache[anim_idx]['action']
Expand All @@ -176,7 +176,7 @@ def get_or_create_action_and_slot(gltf, vnode_idx, anim_idx, path):

action.layers[0].strips[0].channelbags.new(slot)

gltf.action_cache[anim_idx]['object_slots'][obj.name][slot.id_root] = (action, slot)
gltf.action_cache[anim_idx]['object_slots'][obj.name][slot.target_id_type] = (action, slot)
else:
action, slot = ac_sl

Expand Down

0 comments on commit 9b3176b

Please sign in to comment.