Incorrect bones matrix calculation when exporting to Fbx #56883

Open
opened 2018-09-23 14:52:13 +02:00 by lucas veber · 10 comments

System Information
Win 10

Blender Version
Broken: 2.79b

Short description of error
Wrong bones rotations are exported at specific frame/values.

Exact steps for others to reproduce the error
Open the blend file attached, export it to Fbx.
Import it back in Blender, or Unity, Unreal... The right thigh has wrong rotation on frame 3.
fbx_fix.blend

**System Information** Win 10 **Blender Version** Broken: 2.79b **Short description of error** Wrong bones rotations are exported at specific frame/values. **Exact steps for others to reproduce the error** Open the blend file attached, export it to Fbx. Import it back in Blender, or Unity, Unreal... The right thigh has wrong rotation on frame 3. [fbx_fix.blend](https://archive.blender.org/developer/F4796184/fbx_fix.blend)
Author

Added subscriber: @LucasVeber

Added subscriber: @LucasVeber
Author

I've found a workaround for this bug.
Decomposing then recomposing the bone matrix fixes it magically in the fbx_utils.py file.

def get_matrix_local(self):
		if self._tag == 'OB':
			return self.bdata.matrix_local.copy()
		elif self._tag == 'DP':
			return self._ref.matrix_world.inverted_safe() * self._dupli_matrix
		else:  # 'BO', current pose
			# PoseBone.matrix is in armature space, bring in back in real local one!
			par = self.bdata.parent	
			c_bone = self._ref.pose.bones[self.bdata.name]
			par_mat_inv = self._ref.pose.bones[par.name].matrix.inverted_safe() if par else Matrix()			
		
			- There's a bug with bones matrix, leading to wrong results when multiplying matrices
			- at some specific rotation values and when scale is different from 1.0
			# Extracting translation, rotation and scale matrices then recompose them seems to fix it		
			t_mat = Matrix.Translation(c_bone.matrix.to_translation())
			r_mat = c_bone.matrix.to_quaternion().to_matrix().to_4x4()			
			s_mat = extract_scale_matrix(c_bone.matrix.to_3x3()).to_4x4()
			bone_mat = t_mat * r_mat * s_mat			
			
			return par_mat_inv * bone_mat

This function is also needed:

def extract_scale_matrix(matrix):
	s_x = Vector((matrix[0][0], matrix[1][0],matrix[2][0])).magnitude
	s_y = Vector((matrix[0][1], matrix[1][1],matrix[2][1])).magnitude
	s_z = Vector((matrix[0][2], matrix[1][2],matrix[2][2])).magnitude		
	s_mat = Matrix(((s_x, 0, 0), (0, s_y, 0), (0, 0, s_z)))
	
	return s_mat

Not sure if I should propose a patch for it, since this is quite clumsy and only works for the Fbx exporter. Seems more like a Blender bug to me. Maybe a developer experienced with the Blender's C++ source matrix functions could fix it in a better way?

I've found a workaround for this bug. Decomposing then recomposing the bone matrix fixes it magically in the fbx_utils.py file. ``` def get_matrix_local(self): if self._tag == 'OB': return self.bdata.matrix_local.copy() elif self._tag == 'DP': return self._ref.matrix_world.inverted_safe() * self._dupli_matrix else: # 'BO', current pose # PoseBone.matrix is in armature space, bring in back in real local one! par = self.bdata.parent c_bone = self._ref.pose.bones[self.bdata.name] par_mat_inv = self._ref.pose.bones[par.name].matrix.inverted_safe() if par else Matrix() - There's a bug with bones matrix, leading to wrong results when multiplying matrices - at some specific rotation values and when scale is different from 1.0 # Extracting translation, rotation and scale matrices then recompose them seems to fix it t_mat = Matrix.Translation(c_bone.matrix.to_translation()) r_mat = c_bone.matrix.to_quaternion().to_matrix().to_4x4() s_mat = extract_scale_matrix(c_bone.matrix.to_3x3()).to_4x4() bone_mat = t_mat * r_mat * s_mat return par_mat_inv * bone_mat ``` This function is also needed: ``` def extract_scale_matrix(matrix): s_x = Vector((matrix[0][0], matrix[1][0],matrix[2][0])).magnitude s_y = Vector((matrix[0][1], matrix[1][1],matrix[2][1])).magnitude s_z = Vector((matrix[0][2], matrix[1][2],matrix[2][2])).magnitude s_mat = Matrix(((s_x, 0, 0), (0, s_y, 0), (0, 0, s_z))) return s_mat ``` Not sure if I should propose a patch for it, since this is quite clumsy and only works for the Fbx exporter. Seems more like a Blender bug to me. Maybe a developer experienced with the Blender's C++ source matrix functions could fix it in a better way?

Added subscriber: @mont29

Added subscriber: @mont29

Changed status from 'Open' to: 'Archived'

Changed status from 'Open' to: 'Archived'
Bastien Montagne self-assigned this 2018-09-30 17:09:06 +02:00

Thanks for the report, but even though I can confirm the issue in 2.7x, I cannot reproduce with 2.80… All efforts are now on 2.8, so I do not intend investigating further why that weird glitch happens in 2.79.

Thanks for the report, but even though I can confirm the issue in 2.7x, I cannot reproduce with 2.80… All efforts are now on 2.8, so I do not intend investigating further *why* that weird glitch happens in 2.79.
Author

Glad to hear it's working fine in 2.8, sure I totally understand 2.79 is no more developed.

Glad to hear it's working fine in 2.8, sure I totally understand 2.79 is no more developed.
Author

Changed status from 'Archived' to: 'Open'

Changed status from 'Archived' to: 'Open'
Author

Sorry, but the bug is still happening in the latest Blender 2.8 build.
Please test and confirm.

Sorry, but the bug is still happening in the latest Blender 2.8 build. Please test and confirm.
Bastien Montagne removed their assignment 2019-08-12 15:59:44 +02:00

Added subscriber: @MattOstgard

Added subscriber: @MattOstgard

I encountered this in the wild and reproduced the issue with latest stable Blender 2.91.0 using the same .blend scene attached to the ticket.

I encountered this in the wild and reproduced the issue with latest stable Blender 2.91.0 using the same .blend scene attached to the ticket.
Sign in to join this conversation.
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender-addons#56883
No description provided.