mirror of https://github.com/H-uru/korman.git
4 changed files with 220 additions and 40 deletions
@ -0,0 +1,92 @@
|
||||
# This file is part of Korman. |
||||
# |
||||
# Korman is free software: you can redistribute it and/or modify |
||||
# it under the terms of the GNU General Public License as published by |
||||
# the Free Software Foundation, either version 3 of the License, or |
||||
# (at your option) any later version. |
||||
# |
||||
# Korman is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with Korman. If not, see <http://www.gnu.org/licenses/>. |
||||
|
||||
import bpy |
||||
from mathutils import Matrix |
||||
import weakref |
||||
from PyHSPlasma import * |
||||
|
||||
from . import utils |
||||
|
||||
class ArmatureConverter: |
||||
def __init__(self, exporter): |
||||
self._exporter = weakref.ref(exporter) |
||||
|
||||
def convert_armature_to_empties(self, bo): |
||||
# Creates Blender equivalents to each bone of the armature, adjusting a whole bunch of stuff along the way. |
||||
# Yes, this is ugly, but required to get anims to export properly. I tried other ways to export armatures, |
||||
# but AFAICT sooner or later you have to implement similar hacks. Might as well create something that the |
||||
# animation exporter can already deal with, with no modification... |
||||
# Don't worry, we'll return a list of temporary objects to clean up after ourselves. |
||||
armature = bo.data |
||||
pose = bo.pose if armature.pose_position == "POSE" else None |
||||
generated_bones = {} # name: Blender empty. |
||||
temporary_objects = [] |
||||
for bone in armature.bones: |
||||
if bone.parent: |
||||
continue |
||||
self._export_bone(bo, bone, bo, Matrix.Identity(4), pose, generated_bones, temporary_objects) |
||||
|
||||
if bo.plasma_modifiers.animation.enabled and bo.animation_data is not None and bo.animation_data.action is not None: |
||||
# Let the anim exporter handle the anim crap. |
||||
temporary_objects.extend(self._exporter().animation.copy_armature_animation_to_temporary_bones(bo, generated_bones)) |
||||
|
||||
return temporary_objects |
||||
|
||||
def _export_bone(self, bo, bone, parent, matrix, pose, generated_bones, temporary_objects): |
||||
bone_empty = bpy.data.objects.new(ArmatureConverter.get_bone_name(bo, bone), None) |
||||
bpy.context.scene.objects.link(bone_empty) |
||||
bone_empty.plasma_object.enabled = True |
||||
|
||||
# Grmbl, animation is relative to rest pose in Blender, and relative to parent in Plasma... |
||||
# Using matrix_parent_inverse or manually adjust keyframes will just mess up rotation keyframes, |
||||
# so let's just insert an extra empty object to correct all that. This is why the CoordinateInterface caches computed matrices, after all... |
||||
bone_parent = bpy.data.objects.new(bone_empty.name + "_REST", None) |
||||
bpy.context.scene.objects.link(bone_parent) |
||||
bone_parent.plasma_object.enabled = True |
||||
bone_parent.parent = parent |
||||
bone_empty.parent = bone_parent |
||||
bone_empty.matrix_local = Matrix.Identity(4) |
||||
|
||||
if pose is not None: |
||||
pose_bone = pose.bones[bone.name] |
||||
bone_empty.rotation_mode = pose_bone.rotation_mode |
||||
pose_matrix = pose_bone.matrix_basis |
||||
else: |
||||
pose_bone = None |
||||
pose_matrix = Matrix.Identity(4) |
||||
|
||||
temporary_objects.append(bone_empty) |
||||
temporary_objects.append(bone_parent) |
||||
generated_bones[bone.name] = bone_empty |
||||
bone_parent.matrix_local = matrix * bone.matrix_local.to_4x4() * pose_matrix |
||||
|
||||
for child in bone.children: |
||||
child_empty = self._export_bone(bo, child, bone_empty, bone.matrix_local.inverted(), pose, generated_bones, temporary_objects) |
||||
return bone_empty |
||||
|
||||
@staticmethod |
||||
def get_bone_name(bo, bone): |
||||
if isinstance(bone, str): |
||||
return "{}_{}".format(bo.name, bone) |
||||
return "{}_{}".format(bo.name, bone.name) |
||||
|
||||
@property |
||||
def _mgr(self): |
||||
return self._exporter().mgr |
||||
|
||||
@property |
||||
def _report(self): |
||||
return self._exporter().report |
Loading…
Reference in new issue