Skip to content

Commit

Permalink
Fixed incorrect mapping of meshes to blend shape bind mesh indices, w…
Browse files Browse the repository at this point in the history
…hich was causing issues adding surfaces inside adjust_mesh_zforward.
  • Loading branch information
ExpiredPopsicle committed Dec 7, 2024
1 parent c6a84a2 commit 7a3a15f
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 19 deletions.
14 changes: 2 additions & 12 deletions addons/godot-vrm/vrm_extension.gd
Original file line number Diff line number Diff line change
Expand Up @@ -480,22 +480,13 @@ func _create_animation_player(animplayer: AnimationPlayer, vrm_extension: Dictio
var nodes = gstate.get_nodes()
var blend_shape_groups = vrm_extension["blendShapeMaster"]["blendShapeGroups"]
# FIXME: Do we need to handle multiple references to the same mesh???
var mesh_idx_to_meshinstance: Dictionary = {}
var mesh_idx_to_meshinstance: Dictionary = vrm_utils.generate_mesh_index_to_meshinstance_mapping(gstate)
var material_name_to_mesh_and_surface_idx: Dictionary = {}
for i in range(meshes.size()):
var gltfmesh: GLTFMesh = meshes[i]
for j in range(gltfmesh.mesh.get_surface_count()):
material_name_to_mesh_and_surface_idx[gltfmesh.mesh.get_surface_material(j).resource_name] = [i, j]

for i in range(nodes.size()):
var gltfnode: GLTFNode = nodes[i]
var mesh_idx: int = gltfnode.mesh
#print("node idx " + str(i) + " node name " + gltfnode.resource_name + " mesh idx " + str(mesh_idx))
if mesh_idx != -1:
var scenenode: ImporterMeshInstance3D = gstate.get_scene_node(i)
mesh_idx_to_meshinstance[mesh_idx] = scenenode
#print("insert " + str(mesh_idx) + " node name " + scenenode.name)

var firstperson = vrm_extension["firstPerson"]

var reset_anim = Animation.new()
Expand All @@ -504,7 +495,6 @@ func _create_animation_player(animplayer: AnimationPlayer, vrm_extension: Dictio
for shape in blend_shape_groups:
#print("Blend shape group: " + shape["name"])
var anim = Animation.new()

for matbind in shape["materialValues"]:
var mesh_and_surface_idx = material_name_to_mesh_and_surface_idx[matbind["materialName"]]
var node: ImporterMeshInstance3D = mesh_idx_to_meshinstance[mesh_and_surface_idx[0]]
Expand Down Expand Up @@ -936,7 +926,7 @@ func _import_post(gstate: GLTFState, node: Node) -> Error:
if is_vrm_0:
# VRM 0.0 has models facing backwards due to a spec error (flipped z instead of x)
var blend_shape_names: Dictionary = vrm_utils._extract_blendshape_names(gltf_json)
vrm_utils.rotate_scene_180(root_node, blend_shape_names)
vrm_utils.rotate_scene_180(root_node, blend_shape_names, gstate)

var do_retarget = true

Expand Down
28 changes: 21 additions & 7 deletions addons/godot-vrm/vrm_utils.gd
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ static func adjust_mesh_zforward(mesh: ImporterMesh, blendshapes: Array):
var mat: Material = surf_data_by_mesh[surf_idx].get("mat")
mesh.add_surface(prim, arr, bsarr, lods, mat, name, fmt_compress_flags)


static func rotate_scene_180_inner(p_node: Node3D, mesh_set: Dictionary, skin_set: Dictionary):
if p_node is Skeleton3D:
for bone_idx in range(p_node.get_bone_count()):
Expand All @@ -85,18 +84,34 @@ static func rotate_scene_180_inner(p_node: Node3D, mesh_set: Dictionary, skin_se
if child is Node3D:
rotate_scene_180_inner(child, mesh_set, skin_set)


static func rotate_scene_180(p_scene: Node3D, blend_shape_names: Dictionary):
static func generate_mesh_index_to_meshinstance_mapping(gstate : GLTFState) -> Dictionary:
var nodes = gstate.get_nodes()
var mesh_idx_to_meshinstance : Dictionary = {}
for i in range(nodes.size()):
var gltfnode: GLTFNode = nodes[i]
var mesh_idx: int = gltfnode.mesh
#print("node idx " + str(i) + " node name " + gltfnode.resource_name + " mesh idx " + str(mesh_idx))
if mesh_idx != -1:
var scenenode: ImporterMeshInstance3D = gstate.get_scene_node(i)
mesh_idx_to_meshinstance[mesh_idx] = scenenode
#print("insert " + str(mesh_idx) + " node name " + scenenode.name)
return mesh_idx_to_meshinstance

static func rotate_scene_180(p_scene: Node3D, blend_shape_names: Dictionary, gstate : GLTFState):
var mesh_set: Dictionary = {}
var skin_set: Dictionary = {}
rotate_scene_180_inner(p_scene, mesh_set, skin_set)
var mesh_index: int = 0
for mesh in mesh_set:

var mesh_idx_to_meshinstance : Dictionary = generate_mesh_index_to_meshinstance_mapping(gstate)

for mesh_index in mesh_idx_to_meshinstance.keys():
var mesh_node = mesh_idx_to_meshinstance[mesh_index]
var mesh = mesh_node.mesh
if mesh_index in blend_shape_names.keys():
adjust_mesh_zforward(mesh, blend_shape_names[mesh_index])
else:
adjust_mesh_zforward(mesh, [])
mesh_index += 1

for skin in skin_set:
for b in range(skin.get_bind_count()):
skin.set_bind_pose(b, ROTATE_180_TRANSFORM * skin.get_bind_pose(b) * ROTATE_180_TRANSFORM)
Expand Down Expand Up @@ -434,7 +449,6 @@ static func _generate_hide_bone_mesh(mesh: ImporterMesh, skin: Skin, bone_names_
new_mesh.add_surface(prim, arr, bsarr, lods, mat, name, fmt_compress_flags)
return new_mesh


static func perform_head_hiding(gstate: GLTFState, mesh_annotations_by_node: Dictionary, head_relative_bones: Dictionary, node_to_head_hidden_node: Dictionary):
var meshes = gstate.get_meshes()
var nodes = gstate.get_nodes()
Expand Down

0 comments on commit 7a3a15f

Please sign in to comment.