# Path: addons/io_scene_gltf_ksons/compat.py
# def mul(x, y): return x @ y
# 
# Path: addons/io_scene_gltf_ksons/mesh.py
# def mesh_name(op, mesh_spec):
#     mesh_idx, primitive_idx = mesh_spec
#     name = op.gltf['meshes'][mesh_idx].get('name', 'meshes[%d]' % mesh_idx)
#     if primitive_idx is not None:
#         # Look for a name on the extras property
#         extras = op.gltf['meshes'][mesh_idx]['primitives'][primitive_idx].get('extras')
#         if type(extras) == dict and type(extras.get('name')) == str and extras['name']:
#             primitive_name = extras['name']
#         else:
#             primitive_name = 'primitives[%d]' % primitive_idx
#         name += '.' + primitive_name
#     return name


from math import pi
from mathutils import Matrix, Quaternion, Vector, Euler
from .compat import mul
from .mesh import mesh_name
#
# So in that case we'll take C(b) = 1, and set
#
#     E(b) = Trans[ Rot[cr(pb)^{-1}] t / cs(pb) ] Rot[cr(pb)^{-1} r]
#     P(b;loadtime) = Scale[s / cs(pb)]
#
# So in both cases we now have LB(b) = L'(b).
#
# TODO: we can still pick a rotation when the scaling is heterogeneous

# Maps an axis into a rotation carrying that axis into +Y
AXIS_TO_PLUS_Y = {
    '-X': Euler([0, 0, -pi/2]).to_quaternion(),
    '+X': Euler([0, 0, pi/2]).to_quaternion(),
    '-Y': Euler([pi, 0, 0]).to_quaternion(),
    '+Y': Euler([0, 0, 0]).to_quaternion(),
    '-Z': Euler([pi/2, 0, 0]).to_quaternion(),
    '+Z': Euler([-pi/2, 0, 0]).to_quaternion(),
}
def adjust_bones(op):
    # List of distances between bone heads (used for computing bone lengths)
    interbone_dists = []

    def visit_bone(vnode):
        t, r, s = vnode.trs

        cr_pb_inv = vnode.parent.correction_rotation.conjugated()
        cs_pb = vnode.parent.correction_homscale

        # Trans[ Rot[cr(pb)^{-1}] t / cs(pb) ]

# Path: addons/io_scene_gltf_ksons/compat.py
# def mul(x, y): return x @ y
# 
# Path: addons/io_scene_gltf_ksons/mesh.py
# def mesh_name(op, mesh_spec):
#     mesh_idx, primitive_idx = mesh_spec
#     name = op.gltf['meshes'][mesh_idx].get('name', 'meshes[%d]' % mesh_idx)
#     if primitive_idx is not None:
#         # Look for a name on the extras property
#         extras = op.gltf['meshes'][mesh_idx]['primitives'][primitive_idx].get('extras')
#         if type(extras) == dict and type(extras.get('name')) == str and extras['name']:
#             primitive_name = extras['name']
#         else:
#             primitive_name = 'primitives[%d]' % primitive_idx
#         name += '.' + primitive_name
#     return name


# Path: addons/io_scene_gltf_ksons/vnode.py
from math import pi
from mathutils import Matrix, Quaternion, Vector, Euler
from .compat import mul
from .mesh import mesh_name

#
# So in that case we'll take C(b) = 1, and set
#
#     E(b) = Trans[ Rot[cr(pb)^{-1}] t / cs(pb) ] Rot[cr(pb)^{-1} r]
#     P(b;loadtime) = Scale[s / cs(pb)]
#
# So in both cases we now have LB(b) = L'(b).
#
# TODO: we can still pick a rotation when the scaling is heterogeneous

# Maps an axis into a rotation carrying that axis into +Y
AXIS_TO_PLUS_Y = {
    '-X': Euler([0, 0, -pi/2]).to_quaternion(),
    '+X': Euler([0, 0, pi/2]).to_quaternion(),
    '-Y': Euler([pi, 0, 0]).to_quaternion(),
    '+Y': Euler([0, 0, 0]).to_quaternion(),
    '-Z': Euler([pi/2, 0, 0]).to_quaternion(),
    '+Z': Euler([-pi/2, 0, 0]).to_quaternion(),
}
def adjust_bones(op):
    # List of distances between bone heads (used for computing bone lengths)
    interbone_dists = []

    def visit_bone(vnode):
        t, r, s = vnode.trs

        cr_pb_inv = vnode.parent.correction_rotation.conjugated()
        cs_pb = vnode.parent.correction_homscale

        # Trans[ Rot[cr(pb)^{-1}] t / cs(pb) ]

        editbone_t = mul(cr_pb_inv, t) / cs_pb