コード例 #1
0
def ik_target_mat(name, index, src):
	mat = Matrix.Translation(Vector(src[0:3]))
	quat = Quaternion(src[3:7])
	mat = mat @ quat.to_matrix().to_4x4()

	src = src[7:]

	ctl_mat = Matrix.Translation(Vector(src[0:3]))
	ctl_quat = Quaternion(src[3:7])
	ctl_mat = ctl_mat @ ctl_quat.to_matrix().to_4x4()
	ctl_scale = Matrix.Scale(src[7], 4, (1, 0, 0))
	ctl_scale @= Matrix.Scale(src[8], 4, (0, 1, 0))
	ctl_scale @= Matrix.Scale(src[9], 4, (0, 0, 1))
	ctl_mat = ctl_mat @ ctl_scale

	obj = bpy.data.objects[name]
	s = obj.animation_retarget_state
	limb = s.ik_limbs[index]
	mapping = s.get_mapping_for_target(limb.target_bone)
	src_arma, src_pose = s.get_pose_and_arma_bone('source', mapping.source)
	dest_arma, dest_pose = s.get_pose_and_arma_bone('target', mapping.target)

	src_world_mat = loc_mat(s.source.matrix_world).inverted() @ s.source.matrix_world
	src_ref_mat = s.source.matrix_world @ loc_mat(src_arma.matrix_local)
	src_rot_mat = rot_mat(s.source.matrix_world) @ rot_mat(src_arma.matrix_local)
	dest_rest_mat = data_to_matrix4x4(mapping.rest)
	dest_rot_mat = rot_mat(s.target.matrix_world) @ rot_mat(dest_rest_mat)
	diff_rot_mat = src_rot_mat.inverted() @ dest_rot_mat

	mat = src_world_mat @ src_ref_mat.inverted() @ loc_mat(dest_rest_mat) @ ctl_mat @ mat @ diff_rot_mat

	return mat
コード例 #2
0
def createBones(bones, name):
    direction = Vector((.01, .01, .01))
    origin = (0, 0, 0)
    bpy.ops.object.add(type='ARMATURE', enter_editmode=True, location=origin)
    ob = bpy.context.object
    ob.show_x_ray = True
    ob.name = name
    amt = ob.data
    amt.name = name + 'Amt'
    amt.show_axes = True
    bpy.ops.object.mode_set(mode='EDIT')
    for (idx, name, pidx, pos, rot_) in bones:
        rot = Quaternion(rot_)
        bone = amt.edit_bones.new(str(idx))
        bone.head = Vector(origin)
        bone.tail = direction
        m = Matrix()
        if pidx != -1:
            pname = bones[pidx][1]
            parent = amt.edit_bones[str(pidx)]
            bone.parent = parent
            P = parent.matrix
            R = rot.to_matrix().to_4x4()
            T = Matrix().Translation(pos)
            m = P * T * R
        else:
            R = rot.to_matrix().to_4x4()
            T = Matrix().Translation(pos)
            m = T * R
        bone.matrix = m

    bpy.ops.object.mode_set(mode='OBJECT')
    return ob
コード例 #3
0
    def apply_rot(self, frame, bone):
        if bone is None:
            return

        values = self.getValue(frame)

        for i in range(len(self.Channels)):
            if isinstance(self.Channels[i], ChannelCachedQuaternion1):
                cached = self.Channels[i]
                val = cached.getValue(frame, values)
                if cached.quatIndex == 0:
                    values = [ val, values[0], values[1], values[2], 0 ]
                elif cached.quatIndex == 1:
                    values = [ values[0], val, values[1], values[2], 0 ]
                elif cached.quatIndex == 2:
                    values = [ values[0], values[1], val, values[2], 0 ]
                elif cached.quatIndex == 3:
                    values = [ values[0], values[1], values[2], val, 0 ]

        rotation = Quaternion((values[3], values[0], values[1], values[2]))

        if bone.bone.parent is not None:
            rotation = bone.bone.convert_local_to_pose(rotation.to_matrix().to_4x4(), bone.bone.matrix.to_4x4(), parent_matrix=bone.bone.parent.matrix_local.to_4x4(), invert=True)
        else:
            rotation = bone.bone.convert_local_to_pose(rotation.to_matrix().to_4x4(), bone.bone.matrix.to_4x4(), invert=True)

        bone.rotation_quaternion = rotation.to_quaternion()
        bone.keyframe_insert(data_path="rotation_quaternion", frame=frame)
コード例 #4
0
ファイル: pose.py プロジェクト: Iffar/makehuman_datagen
def loadMhpFile(context, filepath):
    ob = context.object
    rig = ob.parent
    scn = context.scene
    if rig and rig.type == 'ARMATURE':
        (pname, ext) = os.path.splitext(filepath)
        mhppath = pname + ".mhp"
        
        fp = open(mhppath, "rU")
        for line in fp:
            words = line.split()
            if len(words) < 5:
                continue
            elif words[1] == "quat":
                q = Quaternion((float(words[2]), float(words[3]), float(words[4]), float(words[5])))
                mat = q.to_matrix().to_4x4()
                pb = rig.pose.bones[words[0]]
                pb.matrix_basis = mat
            elif words[1] == "gquat":
                q = Quaternion((float(words[2]), float(words[3]), float(words[4]), float(words[5])))
                mat = q.to_matrix().to_4x4()
                maty = mat[1].copy()
                matz = mat[2].copy()
                mat[1] = -matz
                mat[2] = maty
                pb = rig.pose.bones[words[0]]
                pb.matrix_basis = pb.bone.matrix_local.inverted() * mat
        fp.close()
        print("Mhp file %s loaded" % mhppath)
コード例 #5
0
    def set_bone_transforms(self, bone, node, parent):
        obj = bpy.data.objects[self.blender_armature_name]
        delta = Quaternion((0.7071068286895752, 0.7071068286895752, 0.0, 0.0))

        mat = Matrix()
        if parent is None:
            transform = node.get_transforms()
            mat = transform * delta.to_matrix().to_4x4()
        else:
            if not self.gltf.scene.nodes[
                    parent].is_joint:  # TODO if Node in another scene
                transform = node.get_transforms()
                mat = transform * delta.to_matrix().to_4x4()
            else:
                transform = node.get_transforms()
                parent_mat = obj.data.edit_bones[self.gltf.scene.nodes[
                    parent].blender_bone_name].matrix  # Node in another scene

                mat = (parent_mat.to_quaternion() * delta.inverted() *
                       transform.to_quaternion() * delta).to_matrix().to_4x4()
                mat = Matrix.Translation(parent_mat.to_translation() +
                                         (parent_mat.to_quaternion() *
                                          delta.inverted() *
                                          transform.to_translation())) * mat
                #TODO scaling of bones

        bone.matrix = mat
        return bone.matrix
コード例 #6
0
def transform_rotation(rotation: Quaternion,
                       transform: Matrix = Matrix.Identity(4),
                       need_rotation_correction: bool = False) -> Quaternion:
    """Transform rotation."""
    rotation.normalize()
    correction = Quaternion((2**0.5 / 2, -2**0.5 / 2, 0.0, 0.0))
    m = rotation.to_matrix().to_4x4()
    if need_rotation_correction:
        m @= correction.to_matrix().to_4x4()
    m = transform @ m
    return m.to_quaternion()
コード例 #7
0
def calc_pose_mats(iqmodel, iqpose, bone_axis):
    loc_pose_mat = [None] * len(iqmodel.bones)
    abs_pose_mat = [None] * len(iqmodel.bones)
    recalc = False

    # convert pose to local matrix and compute absolute matrix
    for n in range(len(iqmodel.bones)):
        iqbone = iqmodel.bones[n]

        pose_pos = iqpose[n].translate
        pose_rot = iqpose[n].rotate
        pose_scale = iqpose[n].scale

        local_pos = Vector(pose_pos)
        local_rot = Quaternion(
            (pose_rot[3], pose_rot[0], pose_rot[1], pose_rot[2]))
        local_scale = Vector(pose_scale)

        mat_pos = Matrix.Translation(local_pos)
        mat_rot = local_rot.to_matrix().to_4x4()
        mat_scale = Matrix.Scale(local_scale.x, 3).to_4x4()
        loc_pose_mat[n] = mat_pos * mat_rot * mat_scale

        if iqbone.parent >= 0:
            abs_pose_mat[n] = abs_pose_mat[iqbone.parent] * loc_pose_mat[n]
        else:
            abs_pose_mat[n] = loc_pose_mat[n]

    # Remove negative scaling from bones.
    # Due to numerical instabilities in blender's matrix <-> head/tail/roll math
    # this isn't always stable when the bones are in the X axis. If the bones
    # end up rotated 90 degrees from what they should be, that's the reason.
    for n in range(len(iqmodel.bones)):
        if abs_pose_mat[n].is_negative:
            if not hasattr(iqmodel, 'abs_bind_mat'):
                print("warning: removing negative scale in bone",
                      iqmodel.bones[n].name)
            abs_pose_mat[n] = abs_pose_mat[n] * Matrix.Scale(-1, 4)
            recalc = True

    # flip bone axis (and recompute local matrix if needed)
    if bone_axis == 'X':
        axis_flip = Matrix.Rotation(math.radians(-90), 4, 'Z')
        abs_pose_mat = [m * axis_flip for m in abs_pose_mat]
        recalc = True
    if bone_axis == 'Z':
        axis_flip = Matrix.Rotation(math.radians(-90), 4, 'X')
        abs_pose_mat = [m * axis_flip for m in abs_pose_mat]
        recalc = True

    if recalc:
        inv_pose_mat = [m.inverted() for m in abs_pose_mat]
        for n in range(len(iqmodel.bones)):
            iqbone = iqmodel.bones[n]
            if iqbone.parent >= 0:
                loc_pose_mat[n] = inv_pose_mat[iqbone.parent] * abs_pose_mat[n]
            else:
                loc_pose_mat[n] = abs_pose_mat[n]

    return loc_pose_mat, abs_pose_mat
コード例 #8
0
def get_matrix_world_at_frame(obj, frame_id):
    rotation_mode = get_rotation_mode_at_frame(obj, frame_id)
    if rotation_mode == 'AXIS_ANGLE':
        axis_angle = get_vector4_at_frame(obj, "rotation_axis_angle", frame_id)
        angle = axis_angle[0]
        axis = Vector(axis_angle[1], axis_angle[2], axis_angle[3])
        rotation_matrix = Matrix.Rotation(angle, 4, axis)
    elif rotation_mode == 'QUATERNION':
        rotation_quat = get_vector4_at_frame(obj, "rotation_quaternion",
                                             frame_id)
        quat = Quaternion(rotation_quat)
        rotation_matrix = quat.to_matrix().to_4x4()
    else:
        rotation = get_vector3_at_frame(obj, "rotation_euler", frame_id)
        e = Euler(rotation, rotation_mode)
        rotation_matrix = e.to_matrix().to_4x4()

    location = get_vector3_at_frame(obj, "location", frame_id)
    location_matrix = Matrix.Translation(location).to_4x4()

    scale = get_vector3_at_frame(obj, "scale", frame_id)
    scale_matrix = Matrix.Identity(4)
    scale_matrix[0][0] = scale[0]
    scale_matrix[1][1] = scale[1]
    scale_matrix[2][2] = scale[2]

    return vcu.element_multiply(
        vcu.element_multiply(location_matrix, rotation_matrix), scale_matrix)
コード例 #9
0
def transform_rotation(
    rotation: Quaternion,
    transform: Matrix = Matrix.Identity(4)) -> Quaternion:
    """Transform rotation."""
    m = rotation.to_matrix().to_4x4()
    m = multiply(transform, m)
    return m.to_quaternion()
コード例 #10
0
    def build_armature(self):
        data_block = self.valve_file.get_data_block(block_name='DATA')[0]
        model_skeleton = data_block.data['m_modelSkeleton']
        bone_names = model_skeleton['m_boneName']
        bone_positions = model_skeleton['m_bonePosParent']
        bone_rotations = model_skeleton['m_boneRotParent']
        bone_parents = model_skeleton['m_nParent']

        armature_obj = bpy.data.objects.new(self.name + "_ARM", bpy.data.armatures.new(self.name + "_ARM_DATA"))
        armature_obj.show_in_front = True

        self.main_collection.objects.link(armature_obj)
        bpy.ops.object.select_all(action="DESELECT")
        armature_obj.select_set(True)
        bpy.context.view_layer.objects.active = armature_obj

        armature_obj.rotation_euler = Euler([math.radians(180), 0, math.radians(90)])
        armature = armature_obj.data

        bpy.ops.object.mode_set(mode='EDIT')

        bones = []
        for bone_name in bone_names:
            # print("Creating bone", bone_name)
            bl_bone = armature.edit_bones.new(name=bone_name)
            bl_bone.tail = Vector([0, 0, 1]) + bl_bone.head
            bones.append((bl_bone, bone_name))

        for n, bone_name in enumerate(bone_names):
            bl_bone = armature.edit_bones.get(bone_name)
            parent_id = bone_parents[n]
            if parent_id != -1:
                bl_parent, parent = bones[parent_id]
                bl_bone.parent = bl_parent

        bpy.ops.object.mode_set(mode='POSE')
        for n, (bl_bone, bone_name) in enumerate(bones):
            pose_bone = armature_obj.pose.bones.get(bone_name)
            if pose_bone is None:
                print("Missing", bone_name, 'bone')
            parent_id = bone_parents[n]
            bone_pos = bone_positions[n]
            bone_rot = bone_rotations[n]
            bone_pos = Vector([bone_pos.y, bone_pos.x, -bone_pos.z])
            bone_rot = Quaternion([-bone_rot.w, -bone_rot.y, -bone_rot.x, bone_rot.z])
            mat = (Matrix.Translation(bone_pos) @ bone_rot.to_matrix().to_4x4())
            pose_bone.matrix_basis.identity()

            if parent_id != -1:
                parent_bone = armature_obj.pose.bones.get(bone_names[parent_id])
                pose_bone.matrix = parent_bone.matrix @ mat
            else:
                pose_bone.matrix = mat
        bpy.ops.pose.armature_apply()
        bpy.ops.object.mode_set(mode='OBJECT')
        bpy.ops.object.select_all(action="DESELECT")
        armature_obj.select_set(True)
        bpy.context.view_layer.objects.active = armature_obj
        bpy.ops.object.transform_apply(location=True, rotation=True, scale=False)
        return armature_obj
コード例 #11
0
def create_armature(model: Model, collection):
    bpy.ops.object.armature_add(enter_editmode=True)

    armature_obj: bpy.types.Object = bpy.context.object
    try:
        bpy.context.scene.collection.objects.unlink(armature_obj)
    except:
        pass

    collection.objects.link(armature_obj)
    armature_obj.name = model.name + '_ARM'
    armature: bpy.types.Armature = armature_obj.data
    armature.name = model.name + "_ARM_DATA"

    armature_obj.select_set(True)
    bpy.context.view_layer.objects.active = armature_obj
    bpy.ops.object.mode_set(mode='EDIT')
    armature.edit_bones.remove(armature.edit_bones[0])

    for root_bone in model.armature.roots:
        bone = armature.edit_bones.new(root_bone.name)
        create_child_bones(root_bone, bone, armature)

    for bone in model.armature.bones:  # type: Bone
        bl_bone = armature.edit_bones.get(bone.name)
        bl_bone.tail = Vector([1, 0, 0]) + bl_bone.head

        pos = Vector(bone.position.values)
        rot = Quaternion(bone.rotation.values)
        bl_bone.transform(Matrix.Translation(pos) @ rot.to_matrix().to_4x4())

    bpy.ops.object.mode_set(mode='OBJECT')
    return armature_obj
コード例 #12
0
def rotationMatrix(theta, axis):
    """
    Return the rotation matrix associated with counterclockwise rotation about
    the given axis by theta radians.
    """
    quat_rot = Quaternion(axis, theta)
    return np.array(quat_rot.to_matrix())
コード例 #13
0
def getStoredTPose(rig, useSetKeys):
    for pb in rig.pose.bones:
        quat = Quaternion(pb.McpQuat)
        pb.matrix_basis = quat.to_matrix().to_4x4()
        if useSetKeys:
            setKeys(pb)
    updateScene()
コード例 #14
0
ファイル: t_pose.py プロジェクト: Mitsu1/creaturas-magicas
def loadTPose(rig, filename):
    if filename:
        filepath = os.path.join(os.path.dirname(__file__), filename)
        filepath = os.path.normpath(filepath)
        print("Loading %s" % filepath)
        struct = loadJson(filepath)
        rig.McpTPoseFile = filename
    else:
        return False

    unit = Matrix()
    for pb in rig.pose.bones:
        pb.matrix_basis = unit

    for name, value in struct:
        bname = getBoneName(rig, name)
        try:
            pb = rig.pose.bones[bname]
        except KeyError:
            continue
        quat = Quaternion(value)
        pb.matrix_basis = quat.to_matrix().to_4x4()
        setBoneTPose(pb, quat)

    rig.McpTPoseLoaded = True
    rig.McpRestTPose = False
    return True
コード例 #15
0
ファイル: t_pose.py プロジェクト: jultrunb/ass
def loadTPose(rig, filename):
    if filename:
        filepath = os.path.join(os.path.dirname(__file__), filename)
        filepath = os.path.normpath(filepath)
        print("Loading %s" % filepath)
        struct = loadJson(filepath)
        rig.McpTPoseFile = filename
    else:
        return False

    unit = Matrix()
    for pb in rig.pose.bones:
        pb.matrix_basis = unit

    for name,value in struct:
        bname = getBoneName(rig, name)
        try:
            pb = rig.pose.bones[bname]
        except KeyError:
            continue
        quat = Quaternion(value)
        pb.matrix_basis = quat.to_matrix().to_4x4()
        setBoneTPose(pb, quat)

    rig.McpTPoseLoaded = True
    rig.McpRestTPose = False
    return True
コード例 #16
0
def bone_mat(name, bone, src):
	mat = Matrix.Translation(Vector(src[0:3]))
	quat = Quaternion(src[3:])
	mat = mat @ quat.to_matrix().to_4x4()

	obj = bpy.data.objects[name]
	s = obj.animation_retarget_state
	mapping = s.get_mapping_for_target(bone)
	rest_mat = data_to_matrix4x4(mapping.rest)
	offset_mat = data_to_matrix4x4(mapping.offset)
	src_arma, src_pose = s.get_pose_and_arma_bone('source', mapping.source)
	dest_arma, dest_pose = s.get_pose_and_arma_bone('target', mapping.target)
	src_ref_mat = rot_mat(s.source.matrix_world) @ rot_mat(src_arma.matrix_local)
	dest_ref_mat = rot_mat(s.target.matrix_world) @ rot_mat(rest_mat)
	diff_mat = src_ref_mat. inverted() @ dest_ref_mat
	scale = s.source.scale[0]

	mat.translation *= scale
	mat = diff_mat.inverted() @ mat @ diff_mat
	mat = offset_mat @ mat

	if s.correct_root_pivot and s.root_bone != '' and dest_arma.name == s.root_bone:
		src_root_mat = s.source.matrix_world @ src_arma.matrix_local
		dest_root_mat = s.target.matrix_world @ rest_mat
		src_root_loc = src_root_mat.to_translation()
		dest_root_loc = dest_root_mat.to_translation()
		root_delta_mat = Matrix.Translation(Vector((0,0,(dest_root_loc[2] - src_root_loc[2]))))

		src_rot_matrix = rot_mat(dest_ref_mat @ rot_mat(mat) @ dest_ref_mat.inverted())
		applied_delta_mat = loc_mat((dest_ref_mat.inverted() @ src_rot_matrix) @ root_delta_mat)
		mat = loc_mat(dest_ref_mat.inverted() @ root_delta_mat).inverted() @ applied_delta_mat @ mat

	return mat
コード例 #17
0
    def addBone(bone, armature, obj, parent=None):
        global bone_mapping

        bone_name = bone["attributes"][0]
        bone_mapping.append(bone_name)
        b_bone = armature.edit_bones.new(bone_name)
        b_bone.head = (0, 0, 0)
        b_bone.tail = (0, 0.05, 0)
        b_bone.use_inherit_rotation = True
        b_bone.use_local_location = True
        quad = Quaternion((float(bone["RotationQuaternion"][3]),
                           float(bone["RotationQuaternion"][0]),
                           float(bone["RotationQuaternion"][1]),
                           float(bone["RotationQuaternion"][2])))
        # quad = Quaternion(map(float, bone["RotationQuaternion"]))
        mat = quad.to_matrix().to_4x4()
        b_bone.matrix = mat
        position = Vector(map(float, bone["LocalOffset"]))
        b_bone.translate(position)
        if parent:
            b_bone.parent = parent
            b_bone.matrix = parent.matrix @ b_bone.matrix

        # add child bones
        for children in bone["members"]:
            for child in children["members"]:
                addBone(child, armature, obj, b_bone)
コード例 #18
0
 def execute(self, context):
     selected = bpy.context.selected_objects
     obj = selected[-1]
     surf = bpy.context.scene.objects['surface']
     
     loc = bpy.context.scene.cursor_location
     
     bvh = BVHTree.FromObject(surf, bpy.context.scene)
     
     loc = surf.matrix_world.inverted() * loc
     (loc, normal, index, dist) = bvh.find_nearest(loc)
     if self.use_smooth:
         normal = smooth_normal(surf, loc, index)
     loc = surf.matrix_world * loc
     
     bpy.ops.object.duplicate()
     new_obj = bpy.context.selected_objects[-1]
     
     (unused, surf_rot, unused) = surf.matrix_world.decompose()
     (unused, obj_rot, scale) = obj.matrix_world.decompose()
     
     normal = surf_rot * normal
     vec = obj_rot * Vector((0.0, 0.0, 1.0))
     
     q = vec.rotation_difference(normal)
     q = Quaternion().slerp(q, self.align_with_normal)
     mat_scale = Matrix()
     for i in range(3): mat_scale[i][i] = scale[i]
     new_obj.matrix_world = (Matrix.Translation(loc) *
         q.to_matrix().to_4x4() * obj_rot.to_matrix().to_4x4() *
         mat_scale)
     
     bpy.context.scene.objects.active = new_obj
     
     return {'FINISHED'}
コード例 #19
0
def exportParticles(context, emitter, psys, oct_t):
    """Exports a particle system for the specified emitter"""
    octane = context.scene.octane_render
    export_path = bpath.abspath(octane.path)
    pset = psys.settings
    infostr = "Exporting PS '%s' (%s) on emitter '%s'" % (psys.name, pset.type,
                                                          emitter.name)
    particles = [p for p in psys.particles] if pset.type == 'HAIR' else [
        p for p in psys.particles if p.alive_state == 'ALIVE'
    ]

    if pset.render_type == "OBJECT":
        dupli_ob = pset.dupli_object
        if dupli_ob is not None and octane.instances_write_dupli:
            info(infostr + " with %i instances of '%s' objects" %
                 (len(particles), dupli_ob.name))
            filepath = "".join([bpath.abspath(octane.path), dupli_ob.name])
            info("Writing dupli object to file '%s'" % (filepath + ".obj"))
            dupli_world = dupli_ob.matrix_world.copy()
            transl_inv = Matrix.Translation(-dupli_world.translation)
            dupli_ob.matrix_world = transl_inv * dupli_ob.matrix_world
            writeDupliObjects(context, [dupli_ob], filepath)
            dupli_ob.matrix_world = dupli_world
#
#	elif pset.render_type == "GROUP":
#		duplig = pset.dupli_group
#		if duplig is not None:
#			objects = duplig.objects
#			infostr += " with %i instances from group '%s'" % (len(particles), duplig.name)
#			info(infostr + " {0}".format([o.name for o in objects]))
#			# TODO: separate group scatter per object
    else:
        warning("Invalid PS visualization type '%s'" % pset.render_type)
        return
    if not pset.use_rotation_dupli:
        warning(
            "'Use object rotation' should be on. Rotations wont conform to Blender veiwport"
        )

    try:
        fh = open(export_path + psys.name + ".csv", "w")
        for p in particles:
            #if pset.type == 'HAIR' or not p.alive_state == 'DEAD':
            if (pset.type == "HAIR"):
                loc = Matrix.Translation(p.hair_keys[0].co)
                scale = Matrix.Scale(p.size, 4) * Matrix.Scale(
                    pset.hair_length, 4)
            else:
                loc = Matrix.Translation(p.location)
                scale = Matrix.Scale(p.size, 4)
            rot = Quaternion.to_matrix(p.rotation).to_4x4()
            t = loc * rot * scale
            t = emitter.matrix_world * t if pset.type == "HAIR" else t
            t = oct_t[0] * t * oct_t[1]
            writeTransform(t, fh)
        fh.close()
    except IOError as err:
        msg = "IOError during file handling '{0}'".format(err)
        error(msg)
        raise ExportException(msg)
コード例 #20
0
    def CreateRigHandle(self,
                        handleName,
                        pos: SVector = None,
                        rot: Quaternion = None,
                        group=None,
                        posControl=False,
                        rotControl=False):
        obj = self.obj
        self.edit_mode()
        bone = obj.data.edit_bones.new(name=handleName)
        bone.tail = (Vector([0, 0, 1]) * 0.1) + bone.head
        if pos is not None:
            bone.matrix = bone.matrix @ obj.matrix_world.inverted(
            ) @ Matrix.Translation(pos.v)
        if rot is not None:
            bone.matrix = bone.matrix @ obj.matrix_world.inverted(
            ) @ rot.to_matrix().to_4x4()
        if group is not None:
            bone.bone_group = self._get_bone_group(group)
        dag = Dag(bone)
        self.pose_mode()
        bone = get_bone(obj, dag)
        if not posControl:
            bone.lock_location = [True, True, True]
        if not rotControl:
            bone.lock_rotation_w = True
            bone.lock_rotation[0] = [True, True, True]

        return dag
コード例 #21
0
def getActionRotation(action, bone, frame=1):
    rot = Quaternion()
    rot.identity()
    if bone.rotation_mode != 'QUATERNION':
        rot = Euler(Vector(), bone.rotation_mode)
        for i in range(0, 3):    
            fc = getCurve(action, bone, 'rotation_euler', index = i)
            if fc != None:
                rot[i] = fc.evaluate(frame)
        return rot.to_matrix()
    else:
        for i in range(0, 4):    
            fc = getCurve(action, bone, 'rotation_quaternion', index = i)
            if fc != None:
                rot[i] = fc.evaluate(frame)
        return rot.to_matrix()
    return rot.to_matrix()
コード例 #22
0
def transform_rotation(
    rotation: Quaternion,
    transform: Matrix = Matrix.Identity(4)) -> Quaternion:
    """Transform rotation."""
    rotation.normalize()
    m = rotation.to_matrix().to_4x4()
    m = transform @ m
    return m.to_quaternion()
コード例 #23
0
def transform_to_matrix(pos: Vector, rot: Quaternion, scale: Vector) -> Matrix:
    scale_matrix = Matrix.Diagonal(scale)
    scale_matrix.resize_4x4()
    rot_matrix = rot.to_matrix()
    rot_matrix.resize_4x4()
    pos_matrix = Matrix.Translation(pos.xyz)
    pos_matrix.resize_4x4()
    return pos_matrix @ rot_matrix @ scale_matrix
コード例 #24
0
ファイル: iqe_import.py プロジェクト: uthaman22/asstools
def calc_pose_mats(iqmodel, iqpose, bone_axis):
	loc_pose_mat = [None] * len(iqmodel.bones)
	abs_pose_mat = [None] * len(iqmodel.bones)
	recalc = False

	# convert pose to local matrix and compute absolute matrix
	for n in range(len(iqmodel.bones)):
		iqbone = iqmodel.bones[n]

		pose_pos = iqpose[n].translate
		pose_rot = iqpose[n].rotate
		pose_scale = iqpose[n].scale

		local_pos = Vector(pose_pos)
		local_rot = Quaternion((pose_rot[3], pose_rot[0], pose_rot[1], pose_rot[2]))
		local_scale = Vector(pose_scale)

		mat_pos = Matrix.Translation(local_pos)
		mat_rot = local_rot.to_matrix().to_4x4()
		mat_scale = Matrix.Scale(local_scale.x, 3).to_4x4()
		loc_pose_mat[n] = mat_pos * mat_rot * mat_scale

		if iqbone.parent >= 0:
			abs_pose_mat[n] = abs_pose_mat[iqbone.parent] * loc_pose_mat[n]
		else:
			abs_pose_mat[n] = loc_pose_mat[n]

	# Remove negative scaling from bones.
	# Due to numerical instabilities in blender's matrix <-> head/tail/roll math
	# this isn't always stable when the bones are in the X axis. If the bones
	# end up rotated 90 degrees from what they should be, that's the reason.
	for n in range(len(iqmodel.bones)):
		if abs_pose_mat[n].is_negative:
			if not hasattr(iqmodel, 'abs_bind_mat'):
				print("warning: removing negative scale in bone", iqmodel.bones[n].name)
			abs_pose_mat[n] = abs_pose_mat[n] * Matrix.Scale(-1, 4)
			recalc = True

	# flip bone axis (and recompute local matrix if needed)
	if bone_axis == 'X':
		axis_flip = Matrix.Rotation(math.radians(-90), 4, 'Z')
		abs_pose_mat = [m * axis_flip for m in abs_pose_mat]
		recalc = True
	if bone_axis == 'Z':
		axis_flip = Matrix.Rotation(math.radians(-90), 4, 'X')
		abs_pose_mat = [m * axis_flip for m in abs_pose_mat]
		recalc = True

	if recalc:
		inv_pose_mat = [m.inverted() for m in abs_pose_mat]
		for n in range(len(iqmodel.bones)):
			iqbone = iqmodel.bones[n]
			if iqbone.parent >= 0:
				loc_pose_mat[n] = inv_pose_mat[iqbone.parent] * abs_pose_mat[n]
			else:
				loc_pose_mat[n] = abs_pose_mat[n]

	return loc_pose_mat, abs_pose_mat
コード例 #25
0
 def get_trajectory(self, pose_cw):
     trans_cw = pose_cw[:, :3]
     quat_cw = pose_cw[:, 3:]
     pose_w = []
     for i, _ in enumerate(pose_cw):
         q = Quaternion(quat_cw[i])
         rot = np.array(q.to_matrix())
         pose_w.append(rot @ trans_cw[i])
     return np.array(pose_w)
コード例 #26
0
ファイル: convert.py プロジェクト: P-casper1/BlenderTools
def change_to_scs_quaternion_coordinates(rot):
    """Transposes quaternion rotation from Blender to SCS game engine.

    :param rot: Blender quaternion (or four floats)
    :type rot: Quaternion | list | tuple
    :return: Transposed quaternion rotation
    :rtype: Quaternion
    """
    quat = Quaternion((rot[0], rot[1], rot[2], rot[3]))
    return (scs_to_blend_matrix().inverted() * quat.to_matrix().to_4x4() * scs_to_blend_matrix()).to_quaternion()
コード例 #27
0
def transform_location(location: Vector,
                       transform: Matrix = Matrix.Identity(4),
                       need_rotation_correction: bool = False) -> Vector:
    """Transform location."""
    correction = Quaternion((2**0.5 / 2, -2**0.5 / 2, 0.0, 0.0))
    m = Matrix.Translation(location)
    if need_rotation_correction:
        m @= correction.to_matrix().to_4x4()
    m = transform @ m
    return m.to_translation()
コード例 #28
0
def loadJsonVerts(filepath):
    from .load_json import loadJson
    objects = {}
    rigs = {}
    struct = loadJson(filepath)
    if ("application" not in struct.keys()
            or struct["application"] != "export_basic_data"):
        msg = ("The file\n" + filepath + "           \n" +
               "does not contain basic data")
        raise DazError(msg)

    for figure in struct["figures"]:
        if "num verts" in figure.keys() and figure["num verts"] == 0:
            continue
        name = figure["name"]
        if name not in objects.keys():
            objects[name] = []

        if "vertices" in figure.keys():
            verts = [d2b(vec) for vec in figure["vertices"]]
            objects[name].append(verts)

        if "bones" not in figure.keys():
            continue

        locations = {}
        transforms = {}
        if name not in rigs.keys():
            rigs[name] = []
        rigs[name].append((locations, transforms))
        for bone in figure["bones"]:
            head = Vector(bone["center_point"])
            tail = Vector(bone["end_point"])
            vec = tail - head
            if "ws_transform" in bone.keys():
                ws = bone["ws_transform"]
                rmat = Matrix([ws[0:3], ws[3:6], ws[6:9]])
                head = Vector(ws[9:12])
                tail = head + Mult2(vec, rmat)
            else:
                head = Vector(bone["ws_pos"])
                x, y, z, w = bone["ws_rot"]
                quat = Quaternion((w, x, y, z))
                rmat = quat.to_matrix().to_3x3()
                ws = bone["ws_scale"]
                smat = Matrix([ws[0:3], ws[3:6], ws[6:9]])
                tail = head + Mult3(vec, smat, rmat)
                rmat = Mult2(smat, rmat)
            locations[bone["name"]] = (head, tail)
            rmat = rmat.to_4x4()
            rmat.col[3][0:3] = theSettings.scale * head
            transforms[bone["name"]] = (rmat, head, rmat.to_euler(), (1, 1, 1))

    return objects, rigs
コード例 #29
0
def change_to_scs_quaternion_coordinates(rot):
    """Transposes quaternion rotation from Blender to SCS game engine.

    :param rot: Blender quaternion (or four floats)
    :type rot: Quaternion | list | tuple
    :return: Transposed quaternion rotation
    :rtype: Quaternion
    """
    quat = Quaternion((rot[0], rot[1], rot[2], rot[3]))
    return (scs_to_blend_matrix().inverted() * quat.to_matrix().to_4x4() *
            scs_to_blend_matrix()).to_quaternion()
コード例 #30
0
def exportParticles(context, emitter, psys, oct_t):
	"""Exports a particle system for the specified emitter"""
	octane = context.scene.octane_render
	export_path = bpath.abspath(octane.path)
	pset = psys.settings
	infostr = "Exporting PS '%s' (%s) on emitter '%s'" % (psys.name, pset.type, emitter.name)
	particles = [p for p in psys.particles] if pset.type == 'HAIR' else [p for p in psys.particles if p.alive_state == 'ALIVE']
	
	if pset.render_type == "OBJECT":
		dupli_ob = pset.dupli_object
		if dupli_ob is not None and octane.instances_write_dupli:
			info(infostr + " with %i instances of '%s' objects" % (len(particles), dupli_ob.name))
			filepath = "".join([bpath.abspath(octane.path), dupli_ob.name])
			info("Writing dupli object to file '%s'" % (filepath + ".obj"))
			dupli_world = dupli_ob.matrix_world.copy()
			transl_inv = Matrix.Translation(-dupli_world.translation)
			dupli_ob.matrix_world = transl_inv * dupli_ob.matrix_world
			writeDupliObjects(context, [dupli_ob], filepath)
			dupli_ob.matrix_world = dupli_world
#			
#	elif pset.render_type == "GROUP":
#		duplig = pset.dupli_group
#		if duplig is not None:
#			objects = duplig.objects
#			infostr += " with %i instances from group '%s'" % (len(particles), duplig.name)
#			info(infostr + " {0}".format([o.name for o in objects]))
#			# TODO: separate group scatter per object
	else:
		warning("Invalid PS visualization type '%s'" % pset.render_type)
		return
	if not pset.use_rotation_dupli:
		warning("'Use object rotation' should be on. Rotations wont conform to Blender veiwport")
	
	try:
		fh = open(export_path + psys.name + ".csv", "w")
		for p in particles:
			#if pset.type == 'HAIR' or not p.alive_state == 'DEAD':
			if (pset.type == "HAIR"):
				loc = Matrix.Translation(p.hair_keys[0].co)
				scale = Matrix.Scale(p.size, 4) * Matrix.Scale(pset.hair_length, 4)
			else:
				loc = Matrix.Translation(p.location)
				scale = Matrix.Scale(p.size, 4)
			rot = Quaternion.to_matrix(p.rotation).to_4x4()
			t = loc * rot * scale
			t = emitter.matrix_world * t if pset.type == "HAIR" else t
			t = oct_t[0] * t * oct_t[1]
			writeTransform(t, fh)
		fh.close()
	except IOError as err:
		msg = "IOError during file handling '{0}'".format(err)
		error(msg)
		raise ExportException(msg)
コード例 #31
0
        class Transform(object):
            def __init__(self):
                self.location = Vector()
                self.rotation = Quaternion((1, 0, 0, 0))

            @property
            def matrix(self):
                return Matrix.Translation(
                    self.location) * self.rotation.to_matrix().to_4x4()

            @matrix.setter
            def matrix(self, m):
                self.location, self.rotation, _ = m.decompose()
コード例 #32
0
def pose_bone(root_bone: Bone, armature):
    bl_bone = armature.pose.bones.get(root_bone.name)
    pos = Vector(root_bone.position.values)
    rot = Quaternion(root_bone.rotation.values)
    print(f'Posing "{root_bone.name}" POS:{pos} ROT:{rot}')
    mat = Matrix.Translation(pos) @ rot.to_matrix().to_4x4()
    bl_bone.matrix_basis.identity()
    if bl_bone.parent:
        bl_bone.matrix = bl_bone.parent.matrix @ mat
    else:
        bl_bone.matrix = mat
    for child in root_bone.childs:
        pose_bone(child, armature)
コード例 #33
0
ファイル: hka.py プロジェクト: hanshuogang/Learnbgame
class Transform(object):
    world_scale = 0.1
    world_scale_reciprocal = 10.0  # := 1/world_scale

    def __init__(self):
        self.translation = Vector((0, 0, 0))
        self.rotation = Quaternion()
        self.scale = 1

    def read(self, file):
        v = read_vector4(file)
        q = read_vector4(file)
        scale = read_vector4(file)

        self.translation = Vector(v.xyz) * self.world_scale
        self.rotation = Quaternion(q.wxyz)
        self.scale = scale.z

    def write(self, file):
        v = self.translation * self.world_scale_reciprocal
        v = (v.x, v.y, v.z, 0)
        q = self.rotation
        q = (q.x, q.y, q.z, q.w)
        scale = (self.scale, self.scale, self.scale, 0)

        write_vector4_raw(file, v)
        write_vector4_raw(file, q)
        write_vector4_raw(file, scale)

    def __mul__(self, other):
        t = Transform()
        v = Vector(other.translation)  # dup
        v.rotate(self.rotation)
        t.translation = self.translation + v * self.scale
        t.rotation = self.rotation * other.rotation
        t.scale = self.scale * other.scale
        return t

    def to_matrix(self):
        m_rotation = self.rotation.to_matrix().to_4x4()  # 3x3 to 4x4
        m_scale = Matrix.Scale(self.scale, 4)
        m = m_rotation * m_scale
        m.translation = self.translation
        return m

    def copy(self):
        t = Transform()
        t.translation = self.translation.copy()
        t.rotation = self.rotation.copy()
        t.scale = self.scale
        return t
コード例 #34
0
ファイル: bone_utils.py プロジェクト: pKrime/brignet
def vec_roll_to_mat3_normalized(nor, roll):
    THETA_SAFE = 1.0e-5  # theta above this value are always safe to use
    THETA_CRITICAL = 1.0e-9  # above this is safe under certain conditions

    assert nor.magnitude - 1.0 < 0.01

    x = nor.x
    y = nor.y
    z = nor.z

    theta = 1.0 + y
    theta_alt = x * x + z * z

    # When theta is close to zero (nor is aligned close to negative Y Axis),
    # we have to check we do have non-null X/Z components as well.
    # Also, due to float precision errors, nor can be (0.0, -0.99999994, 0.0) which results
    # in theta being close to zero. This will cause problems when theta is used as divisor.

    bMatrix = Matrix().to_3x3()

    if theta > THETA_SAFE or ((x | z) and theta > THETA_CRITICAL):
        # nor is *not* aligned to negative Y-axis (0,-1,0).
        # We got these values for free... so be happy with it... ;)

        bMatrix[0][1] = -x
        bMatrix[1][0] = x
        bMatrix[1][1] = y
        bMatrix[1][2] = z
        bMatrix[2][1] = -z

        if theta > THETA_SAFE:
            # nor differs significantly from negative Y axis (0,-1,0): apply the general case. */
            bMatrix[0][0] = 1 - x * x / theta
            bMatrix[2][2] = 1 - z * z / theta
            bMatrix[2][0] = bMatrix[0][2] = -x * z / theta
        else:
            # nor is close to negative Y axis (0,-1,0): apply the special case. */
            bMatrix[0][0] = (x + z) * (x - z) / -theta_alt
            bMatrix[2][2] = -bMatrix[0][0]
            bMatrix[2][0] = bMatrix[0][2] = 2.0 * x * z / theta_alt
    else:
        # nor is very close to negative Y axis (0,-1,0): use simple symmetry by Z axis. */
        bMatrix.identity()
        bMatrix[0][0] = bMatrix[1][1] = -1.0

    # Make Roll matrix */
    quat = Quaternion(nor, roll)
    rMatrix = quat.to_matrix()

    # Combine and output result */
    return rMatrix @ bMatrix
コード例 #35
0
 def get_ground_align_matrix(self, norm, pos, asset):
     scale = bpy.data.objects[asset.ref_object_name].scale.to_tuple()
     m = Matrix()
     m[0][0], m[1][1], m[2][2] = scale
     scale = m
     surface_rotation = Vector(
         (0, 0, 1)).rotation_difference(norm).normalized()
     object_rotation = Quaternion().slerp(surface_rotation,
                                          asset.surface_affect)
     rot = object_rotation.to_matrix().normalized()
     trans = rot.to_4x4()
     trans.translation = (pos + Vector((0, 0, asset.z_offset)))
     trans *= Matrix.Rotation(asset.start_rot_z, 4, 'Z')
     return trans * scale
コード例 #36
0
ファイル: pose_util.py プロジェクト: AnthonyZhai/yolo9d
def get_3x4_RT_matrix(location, rotation):
    '''

    :param location:
    :param rotation:
    :return: RT_matrix
    '''
    rot = Quaternion(rotation)
    T = Vector(location)

    R = rot.to_matrix()

    # put into 3x4 matrix
    RT = Matrix((R[0][:] + (T[0], ), R[1][:] + (T[1], ), R[2][:] + (T[2], )))
    return RT
コード例 #37
0
ファイル: t_pose.py プロジェクト: ihavenick/MakeHuman
def setTPose(context):
    rig = context.object
    scn = context.scene
    if not rig.McpHasTPose:
        print(("%s has no defined T-pose" % rig))

    quat = Quaternion((1,0,0,0))
    mat = quat.to_matrix().to_4x4()
    for pb in rig.pose.bones:
        try:
            qw = pb["McpRestW"]
        except KeyError:
            continue
        pb.matrix_basis = mat
    print("Set T-pose")
コード例 #38
0
ファイル: t_pose.py プロジェクト: ihavenick/MakeHuman
def clearTPose(context):
    rig = context.object
    scn = context.scene
    if not rig.McpHasTPose:
        print(("%s has no defined T-pose" % rig))

    for pb in rig.pose.bones:
        try:
            qw = pb["McpRestW"]
            qx = pb["McpRestX"]
            qy = pb["McpRestY"]
            qz = pb["McpRestZ"]
        except KeyError:
            continue
        quat = Quaternion((qw,qx,qy,qz))
        pb.matrix_basis = quat.to_matrix().to_4x4()
    print("Cleared T-pose")
コード例 #39
0
ファイル: depath.py プロジェクト: Cx-01/myblendercontrib
def bake_path_offsets(context, cu_path, ob, action, specials):
    """ bake path offsets into an action """
    channels = get_bone_channels(action)
    channels = topmost_level(channels, ob, specials)
    limits = (int(action.frame_range[0]), 2  + int(action.frame_range[1]))
    values = evaluate_curves(channels, limits)
    zero_offset = get_path_offset(context, cu_path, ob, 0).copy()
    for bone, groups in channels.items():

        for data_path, curves in groups.items():
            data = [(cu.data_path, cu.array_index, cu.group.name) for cu in curves]
            while curves:
                cu = curves.pop(-1)
                action.fcurves.remove(cu)
            for datum in data:
                cu = action.fcurves.new(datum[0], datum[1], datum[2])
                curves.append(cu)
    for frame in range(limits[0], limits[1]):
        context.scene.frame_set(frame)
        current_offset = ob.matrix_world
        print(ob.name, current_offset.to_translation() , zero_offset.to_translation())
        for bone, groups in channels.items():
            for transforms in 'location', 'rotation_quaternion':
                if 'location' in groups:
                    old_loc = values[bone]['location'][frame - limits[0]]
                else:
                    old_loc = Vector((0,0,0))
                if 'rotation_quaternion' in groups:
                    old_rot = Quaternion(values[bone]['rotation_quaternion'][frame - limits[0]])
                else:
                    old_rot = Quaternion((1, 0, 0, 0))
            old_trans = Matrix.Translation(old_loc).to_4x4() * old_rot.to_matrix().to_4x4()
            rest_mat = ob.data.bones[bone].matrix_local
            old_trans_world = current_offset * rest_mat * old_trans
            new_trans =\
                rest_mat.inverted() * zero_offset.inverted() * old_trans_world
            new_loc, new_rot, sca = new_trans.decompose()
            for group, curves in groups.items():
                for array_index, curve in enumerate(curves):
                    if curve.data_path.endswith('location'):
                        insert_keyframe_curve(
                            curve, frame, new_loc[array_index], 'LINEAR')
                    else:
                        insert_keyframe_curve(
                            curve, frame, new_rot[array_index], 'LINEAR')
コード例 #40
0
ファイル: t_pose.py プロジェクト: ihavenick/MakeHuman
def createTPose(context):
    rig = context.object
    scn = context.scene
    if rig.McpHasTPose:
        setTPose(context)
        return

    filepath = os.path.join(os.path.dirname(__file__), "t_pose.json")
    struct = loadJson(filepath)

    for name,value in struct:
        pb = rig.pose.bones[name]
        quat = Quaternion(value)
        pb.matrix_basis = quat.to_matrix().to_4x4()
        rest = quat.inverted()
        pb["McpRestW"] = rest.w
        pb["McpRestX"] = rest.x
        pb["McpRestY"] = rest.y
        pb["McpRestZ"] = rest.z

    children = []
    for ob in scn.objects:
        if ob.type != 'MESH':
            continue
        for mod in ob.modifiers:
            if (mod.type == 'ARMATURE' and
                mod.object == rig):
                children.append((ob, mod.name))
                scn.objects.active = ob
                bpy.ops.object.modifier_apply(apply_as='SHAPE', modifier=mod.name)
                ob.data.shape_keys.key_blocks[mod.name].value = 1

    scn.objects.active = rig
    bpy.ops.pose.armature_apply()
    for ob,name in children:
        scn.objects.active = ob
        mod = ob.modifiers.new(name, 'ARMATURE')
        mod.object = rig
        mod.use_vertex_groups = True
        bpy.ops.object.modifier_move_up(modifier=name)
        setShapeKey(ob, name, 1.0)

    scn.objects.active = rig
    rig.McpHasTPose = True
    print("Created T-pose")
コード例 #41
0
	def getmatrix(self):

		# Rotating / panning / zooming 3D view is handled here.
		# Get matrix.
		if self.selobj.rotation_mode == 'AXIS_ANGLE':
			# when roataion mode is axisangle
			angle, x, y, z =  self.selobj.rotation_axis_angle
			self.matrix = Matrix.Rotation(-angle, 4, Vector((x, y, z)))
		elif self.selobj.rotation_mode == 'QUATERNION':
			# when rotation on object is quaternion
			w, x, y, z = self.selobj.rotation_quaternion
			x = -x
			y = -y
			z = -z
			quat = Quaternion([w, x, y, z])
			self.matrix = quat.to_matrix()
			self.matrix.resize_4x4()
		else:
			# when rotation of object is euler
			ax, ay, az = self.selobj.rotation_euler
			mat_rotX = Matrix.Rotation(-ax, 4, 'X')
			mat_rotY = Matrix.Rotation(-ay, 4, 'Y')
			mat_rotZ = Matrix.Rotation(-az, 4, 'Z')
		if self.selobj.rotation_mode == 'XYZ':
			self.matrix = mat_rotX * mat_rotY * mat_rotZ
		elif self.selobj.rotation_mode == 'XZY':
			self.matrix = mat_rotX * mat_rotZ * mat_rotY
		elif self.selobj.rotation_mode == 'YXZ':
			self.matrix = mat_rotY * mat_rotX * mat_rotZ
		elif self.selobj.rotation_mode == 'YZX':
			self.matrix = mat_rotY * mat_rotZ * mat_rotX
		elif self.selobj.rotation_mode == 'ZXY':
			self.matrix = mat_rotZ * mat_rotX * mat_rotY
		elif self.selobj.rotation_mode == 'ZYX':
			self.matrix = mat_rotZ * mat_rotY * mat_rotX

		# handle object scaling
		sx, sy, sz = self.selobj.scale
		mat_scX = Matrix.Scale(sx, 4, Vector([1, 0, 0]))
		mat_scY = Matrix.Scale(sy, 4, Vector([0, 1, 0]))
		mat_scZ = Matrix.Scale(sz, 4, Vector([0, 0, 1]))
		self.matrix = mat_scX * mat_scY * mat_scZ * self.matrix
コード例 #42
0
ファイル: wld_bpy.py プロジェクト: pixelbound/equilibre
def importSkeletonPiece(skel, tree, piece, parentName, depth=0):
    bone = skel.edit_bones.new(piece.name)
    track = piece.trackRef.Reference
    trans = Vector(track.translation())
    rot = Quaternion(track.rotation())
    mTrans = Matrix.Translation(trans)
    mRot = rot.to_matrix()
    mRot.resize_4x4()
    if parentName:
        parent = skel.edit_bones[parentName]
        bone.parent = parent
        bone.head = parent.tail
        bone.use_connect = False
        m = parent.matrix.copy()
    else:
        bone.head = (0, 0, 0)
        m = Matrix()
    m = m * mTrans
    m = m * mRot
    bone.tail = transform(m, bone.head)
    # recursively import the children bones
    for childID in piece.children:
        importSkeletonPiece(skel, tree, tree[childID], piece.name, depth+1)
コード例 #43
0
ファイル: character.py プロジェクト: willcode4fun/scriptools
def drawBone2(p1, p2, radiuses, material):
  length = dist(p1,p2)
  print('length :',length)
  v = Vector(diffv(p1, p2))
  up = Vector((0,0,1))
  if v!=-up:
    rot = up.rotation_difference(v)
  else:
    rot = Quaternion((1,0,0),math.pi)
  s1 = drawEllipsoid((0,0,-0.5*length),radiuses,material)
  s2 = drawEllipsoid((0,0,0.5*length),radiuses,material)
  c1 = drawCylinder(zero,radiuses,length,materials.blue)
  s1.select = True
  s2.select = True
  c1.select = True
  #bpy.ops.transform.translate(value=(0,0,length/2))
  #bpy.ops.object.editmode_toggle()
  bpy.ops.transform.rotate(value=rot.angle, axis=rot.axis)
  #bpy.ops.object.editmode_toggle()
  #bpy.ops.transform.translate(value=Vector((0,0,-0.5*length))*rot.to_matrix())
  rot.normalize();
  bpy.ops.transform.translate(value=Vector((0,0,0.5*length))*rot.to_matrix())
  bpy.ops.transform.translate(value=p1)
  return (s1,s2,c1)
コード例 #44
0
ファイル: pose.py プロジェクト: jultrunb/ass
def loadMhpFile(context, filepath):
    ob = context.object
    if ob.type == "ARMATURE":
        rig = ob
    else:
        rig = ob.parent

    unit = Matrix()
    for pb in rig.pose.bones:
        pb.matrix_basis = unit

    scn = context.scene
    if rig and rig.type == "ARMATURE":
        (pname, ext) = os.path.splitext(filepath)
        mhppath = pname + ".mhp"

        fp = open(mhppath, "rU")
        for line in fp:
            words = line.split()
            if len(words) < 4:
                continue
            try:
                pb = rig.pose.bones[words[0]]
            except KeyError:
                continue

            if isMuscleBone(pb):
                pass
            elif words[1] == "quat":
                q = Quaternion((float(words[2]), float(words[3]), float(words[4]), float(words[5])))
                mat = q.to_matrix().to_4x4()
                pb.matrix_basis = mat
            elif words[1] == "gquat":
                q = Quaternion((float(words[2]), float(words[3]), float(words[4]), float(words[5])))
                mat = q.to_matrix().to_4x4()
                maty = mat[1].copy()
                matz = mat[2].copy()
                mat[1] = -matz
                mat[2] = maty
                pb.matrix_basis = pb.bone.matrix_local.inverted() * mat
            elif words[1] == "matrix":
                rows = []
                n = 2
                for i in range(4):
                    rows.append((float(words[n]), float(words[n + 1]), float(words[n + 2]), float(words[n + 3])))
                    n += 4
                mat = Matrix(rows)
                if pb.parent:
                    pb.matrix_basis = mat
                else:
                    maty = mat[1].copy()
                    matz = mat[2].copy()
                    mat[1] = -matz
                    mat[2] = maty
                    pb.matrix_basis = pb.bone.matrix_local.inverted() * mat
            elif words[1] == "scale":
                pass
            else:
                raise MHError("Unknown line in mcp file:\n%s" % line)
        fp.close()
        print("Mhp file %s loaded" % mhppath)
コード例 #45
0
ファイル: t_pose.py プロジェクト: jultrunb/ass
def getStoredBonePose(pb):
    try:
        quat = Quaternion((pb.McpQuatW, pb.McpQuatX, pb.McpQuatY, pb.McpQuatZ))
    except KeyError:
        quat = Quaternion()
    return quat.to_matrix().to_4x4()
コード例 #46
0
ファイル: frme.py プロジェクト: AxioDL/hecl
def recursive_cook(buffer, obj, version, path_hasher, parent_name):
    buffer += struct.pack('>4s', obj.retro_widget_type[6:].encode())
    buffer += obj.name.encode() + b'\0'
    buffer += parent_name.encode() + b'\0'
    buffer += struct.pack('>bbbbffffI',
        False,
        obj.retro_widget_default_visible,
        obj.retro_widget_default_active,
        obj.retro_widget_cull_faces,
        obj.retro_widget_color[0],
        obj.retro_widget_color[1],
        obj.retro_widget_color[2],
        obj.retro_widget_color[3],
        model_draw_flags_e[obj.retro_widget_model_draw_flags])

    angle = Quaternion((1.0, 0.0, 0.0), 0)

    if obj.retro_widget_type == 'RETRO_CAMR':
        angle = Quaternion((1.0, 0.0, 0.0), math.radians(-90.0))
        aspect = bpy.context.scene.render.resolution_x / bpy.context.scene.render.resolution_y

        if obj.data.type == 'PERSP':
            if aspect > 1.0:
                fov = math.degrees(math.atan(math.tan(obj.data.angle / 2.0) / aspect)) * 2.0
            else:
                fov = math.degrees(obj.data.angle)
            buffer += struct.pack('>Iffff', 0, fov, aspect, obj.data.clip_start, obj.data.clip_end)

        elif obj.data.type == 'ORTHO':
            ortho_half = obj.data.ortho_scale / 2.0
            buffer += struct.pack('>Iffffff', 1, -ortho_half, ortho_half, ortho_half / aspect,
                                  -ortho_half / aspect, obj.data.clip_start, obj.data.clip_end)

    elif obj.retro_widget_type == 'RETRO_MODL':
        if len(obj.children) == 0:
            raise RuntimeException('Model Widget must have a child model object')
        model_obj = obj.children[0]
        if model_obj.type != 'MESH':
            raise RuntimeException('Model Widget must have a child MESH')
        if not model_obj.data.library:
            raise RuntimeException('Model Widget must have a linked library MESH')
        path = bpy.path.abspath(model_obj.data.library.filepath)
        path_hash = path_hasher.hashpath32(path)
        buffer += struct.pack('>III', path_hash, 0, obj.retro_model_light_mask)

    elif obj.retro_widget_type == 'RETRO_PANE':
        buffer += struct.pack('>fffff',
                              obj.retro_pane_dimensions[0],
                              obj.retro_pane_dimensions[1],
                              obj.retro_pane_scale_center[0],
                              obj.retro_pane_scale_center[1],
                              obj.retro_pane_scale_center[2])

    elif obj.retro_widget_type == 'RETRO_TXPN':
        path_hash = path_hasher.hashpath32(obj.retro_textpane_font_path)
        buffer += struct.pack('>fffffIbbIIffffffffff',
                              obj.retro_pane_dimensions[0],
                              obj.retro_pane_dimensions[1],
                              obj.retro_pane_scale_center[0],
                              obj.retro_pane_scale_center[1],
                              obj.retro_pane_scale_center[2],
                              path_hash,
                              obj.retro_textpane_word_wrap,
                              obj.retro_textpane_horizontal,
                              hjustifications[obj.retro_textpane_hjustification],
                              vjustifications[obj.retro_textpane_vjustification],
                              obj.retro_textpane_fill_color[0],
                              obj.retro_textpane_fill_color[1],
                              obj.retro_textpane_fill_color[2],
                              obj.retro_textpane_fill_color[3],
                              obj.retro_textpane_outline_color[0],
                              obj.retro_textpane_outline_color[1],
                              obj.retro_textpane_outline_color[2],
                              obj.retro_textpane_outline_color[3],
                              obj.retro_textpane_block_extent[0],
                              obj.retro_textpane_block_extent[1])
        if version >= 1:
            path_hash = path_hasher.hashpath32(obj.retro_textpane_jp_font_path)
            buffer += struct.pack('>III',
                                  path_hash,
                                  obj.retro_textpane_jp_font_scale[0],
                                  obj.retro_textpane_jp_font_scale[1])

    elif obj.retro_widget_type == 'RETRO_TBGP':
        buffer += struct.pack('>HHIHHbbffbfHHHH',
                              obj.retro_tablegroup_elem_count,
                              0,
                              0,
                              obj.retro_tablegroup_elem_default,
                              0,
                              obj.retro_tablegroup_wraparound,
                              False,
                              0.0,
                              0.0,
                              False,
                              0.0,
                              0,
                              0,
                              0,
                              0)

    elif obj.retro_widget_type == 'RETRO_GRUP':
        buffer += struct.pack('>Hb',
                              obj.retro_group_default_worker,
                              False)

    elif obj.retro_widget_type == 'RETRO_SLGP':
        buffer += struct.pack('>ffff',
                              obj.retro_slider_min,
                              obj.retro_slider_max,
                              obj.retro_slider_default,
                              obj.retro_slider_increment)

    elif obj.retro_widget_type == 'RETRO_ENRG':
        path_hash = path_hasher.hashpath32(obj.retro_energybar_texture_path)
        buffer += struct.pack('>I', path_hash)

    elif obj.retro_widget_type == 'RETRO_METR':
        buffer += struct.pack('>bbII',
                              False,
                              obj.retro_meter_no_round_up,
                              obj.retro_meter_max_capacity,
                              obj.retro_meter_worker_count)

    elif obj.retro_widget_type == 'RETRO_LITE':
        angle = Quaternion((1.0, 0.0, 0.0), math.radians(-90.0))
        type_enum = 0
        constant = 1.0
        linear = 0.0
        quadratic = 0.0
        cutoff = 0.0
        if obj.data.type == 'POINT':
            type_enum = 4
        elif obj.data.type == 'HEMI':
            type_enum = 2
        elif obj.data.type == 'SPOT':
            type_enum = 0
            cutoff = obj.data.spot_size

        if obj.data.type == 'POINT' or obj.data.type == 'SPOT':
            constant = obj.data.constant_coefficient
            linear = obj.data.linear_coefficient
            quadratic = obj.data.quadratic_coefficient

        buffer += struct.pack('>IffffffI',
                              type_enum, constant, linear, quadratic,
                              obj.data.retro_light_angle_constant,
                              obj.data.retro_light_angle_linear,
                              obj.data.retro_light_angle_quadratic,
                              obj.data.retro_light_index)
        if obj.data.type == 'SPOT':
            buffer += struct.pack('>f', cutoff)

    elif obj.retro_widget_type == 'RETRO_IMGP':
        if obj.type != 'MESH':
            raise RuntimeException('Imagepane Widget must be a MESH')
        if len(obj.data.loops) < 4:
            raise RuntimeException('Imagepane Widget must be a MESH with 4 verts')
        if len(obj.data.uv_layers) < 1:
            raise RuntimeException('Imagepane Widget must ba a MESH with a UV layer')
        path_hash = 0xffffffff
        if len(obj.data.materials):
            material = obj.data.materials[0]
            if len(material.texture_slots) and material.texture_slots[0]:
                tex_slot = material.texture_slots[0]
                if tex_slot.texture.type == 'IMAGE' and tex_slot.texture.image:
                    image = tex_slot.texture.image
                    path = bpy.path.abspath(image.filepath)
                    path_hash = path_hasher.hashpath32(path)

        buffer += struct.pack('>IIII', path_hash, 0, 0, 4)
        for i in range(4):
            vi = obj.data.loops[i].vertex_index
            co = obj.data.vertices[vi].co
            buffer += struct.pack('>fff', co[0], co[1], co[2])

        buffer += struct.pack('>I', 4)
        for i in range(4):
            co = obj.data.uv_layers[0].data[i].uv
            buffer += struct.pack('>ff', co[0], co[1])

    if obj.retro_widget_is_worker:
        buffer += struct.pack('>bH', True, obj.retro_widget_worker_id)
    else:
        buffer += struct.pack('>b', False)

    angMtx = angle.to_matrix() * obj.matrix_local.to_3x3()
    buffer += struct.pack('>fffffffffffffffIH',
        obj.matrix_local[0][3],
        obj.matrix_local[1][3],
        obj.matrix_local[2][3],
        angMtx[0][0], angMtx[0][1], angMtx[0][2],
        angMtx[1][0], angMtx[1][1], angMtx[1][2],
        angMtx[2][0], angMtx[2][1], angMtx[2][2],
        0.0, 0.0, 0.0, 0, 0)

    ch_list = []
    for ch in obj.children:
        ch_list.append((ch.pass_index, ch.name))
    for s_pair in sorted(ch_list):
        ch = bpy.data.objects[s_pair[1]]
        if ch.retro_widget_type != 'RETRO_NONE':
            recursive_cook(buffer, ch, version, path_hasher, obj.name)
コード例 #47
0
def transform_rotation(rotation: Quaternion, transform: Matrix = Matrix.Identity(4)) -> Quaternion:
    """Transform rotation."""
    rotation.normalize()
    m = rotation.to_matrix().to_4x4()
    m = multiply(transform, m)
    return m.to_quaternion()
コード例 #48
0
class SelProject(bpy.types.Operator):
	bl_idname = "mesh.selproject"
	bl_label = "SelProject"
	bl_description = "Use object projection as selection tool"
	bl_options = {'REGISTER', 'UNDO'}

	def invoke(self, context, event):

		global started

		started = True

		self.area = context.area
		self.area.header_text_set(text="SelProject :  Enter to confirm - ESC to exit")

		self.init_selproject(context)

		context.window_manager.modal_handler_add(self)

		self._handle = bpy.types.SpaceView3D.draw_handler_add(self.redraw, (), 'WINDOW', 'POST_PIXEL')

		return {'RUNNING_MODAL'}


	def modal(self, context, event):

		global started

		if event.type in {'RET', 'NUMPAD_ENTER'}:
			self.area.header_text_set()
			if self.obhide != None:
				bpy.ops.object.select_all(action = 'DESELECT')
				self.obF.select = True
				bpy.context.scene.objects.active = self.obF
				bpy.ops.object.delete()
				self.obhide.hide = False
			bpy.ops.object.select_all(action = 'DESELECT')
			self.empt.select = True
			bpy.context.scene.objects.active = self.empt
			bpy.ops.object.delete()
			self.obT.select = True
			bpy.context.scene.objects.active = self.obT
			started = False
			for v in self.vsellist:
				v.select = True
			for e in self.esellist:
				e.select = True
			for f in self.fsellist:
				f.select = True
			self.obF.location = self.originobF
			self.obT.location = self.originobT
			self.bmT.select_flush(1)
			self.bmT.to_mesh(self.meT)
			self.meT.update()
			self.bmF.free()
			self.bmT.free()
			bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
			bpy.ops.object.editmode_toggle()
			return {'FINISHED'}

		elif event.type == 'ESC':
			self.area.header_text_set()
			if self.obhide != None:
				bpy.ops.object.select_all(action = 'DESELECT')
				self.obF.select = True
				bpy.context.scene.objects.active = self.obF
				bpy.ops.object.delete()
				self.obhide.hide = False
			bpy.ops.object.select_all(action = 'DESELECT')
			self.empt.select = True
			bpy.context.scene.objects.active = self.empt
			bpy.ops.object.delete()
			started = False
			self.obF.location = self.originobF
			self.obT.location = self.originobT
			self.bmF.free()
			self.bmT.free()
			for obj in self.oldobjlist:
				obj.select = True
			self.scn.objects.active = self.oldobj
			bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
			if self.oldmode == 'EDIT':
				bpy.ops.object.editmode_toggle()
			return {'CANCELLED'}

		elif event.type in {'LEFTMOUSE', 'MIDDLEMOUSE', 'RIGHTMOUSE', 'WHEELDOWNMOUSE', 'WHEELUPMOUSE', 'G', 'S', 'R', 'X', 'Y', 'Z', 'MOUSEMOVE'}:
			context.region.tag_redraw()
			return {'PASS_THROUGH'}

		return {'RUNNING_MODAL'}


	def getmatrix(self, selobj):

		# Rotating / panning / zooming 3D view is handled here.
		# Creates a matrix.
		if selobj.rotation_mode == 'AXIS_ANGLE':
			# object rotation_quaternionmode axisangle
			ang, x, y, z =  selobj.rotation_axis_angle
			matrix = Matrix.Rotation(-ang, 4, Vector((x, y, z)))
		elif selobj.rotation_mode == 'QUATERNION':
			# object rotation_quaternionmode euler
			w, x, y, z = selobj.rotation_quaternion
			x = -x
			y = -y
			z = -z
			self.quat = Quaternion([w, x, y, z])
			matrix = self.quat.to_matrix()
			matrix.resize_4x4()
		else:
			# object rotation_quaternionmode euler
			ax, ay, az = selobj.rotation_euler
			mat_rotX = Matrix.Rotation(-ax, 4, 'X')
			mat_rotY = Matrix.Rotation(-ay, 4, 'Y')
			mat_rotZ = Matrix.Rotation(-az, 4, 'Z')
		if selobj.rotation_mode == 'XYZ':
			matrix = mat_rotX * mat_rotY * mat_rotZ
		elif selobj.rotation_mode == 'XZY':
			matrix = mat_rotX * mat_rotZ * mat_rotY
		elif selobj.rotation_mode == 'YXZ':
			matrix = mat_rotY * mat_rotX * mat_rotZ
		elif selobj.rotation_mode == 'YZX':
			matrix = mat_rotY * mat_rotZ * mat_rotX
		elif selobj.rotation_mode == 'ZXY':
			matrix = mat_rotZ * mat_rotX * mat_rotY
		elif selobj.rotation_mode == 'ZYX':
			matrix = mat_rotZ * mat_rotY * mat_rotX

		# handle object scaling
		sx, sy, sz = selobj.scale
		mat_scX = Matrix.Scale(sx, 4, Vector([1, 0, 0]))
		mat_scY = Matrix.Scale(sy, 4, Vector([0, 1, 0]))
		mat_scZ = Matrix.Scale(sz, 4, Vector([0, 0, 1]))
		matrix = mat_scX * mat_scY * mat_scZ * matrix

		return matrix


	def getscreencoords(self, vector):
		# calculate screencoords of given Vector
		vector = vector * self.matrixT
		vector = vector + self.obT.location

		svector = bpy_extras.view3d_utils.location_3d_to_region_2d(self.region, self.rv3d, vector)
		if svector == None:
			return [0, 0]
		else:
			return [svector[0], svector[1]]




	def checksel(self):

		self.selverts = []
		self.matrixT = self.getmatrix(self.obT)
		self.matrixF = self.getmatrix(self.obF).inverted()
		direc1 =  (self.obF.location - self.empt.location) * self.matrixF
		direc2 =  (self.obF.location - self.empt.location) * self.matrixT.inverted()
		direc2.length = 10000
		for v in self.bmT.verts:
			vno1 = v.normal
			vno1.length = 0.0001
			vco1 = v.co + vno1
			hit1 = self.obT.ray_cast(vco1, vco1 + direc2)
			vno2 = -v.normal
			vno2.length = 0.0001
			vco2 = v.co + vno2
			hit2 = self.obT.ray_cast(vco2, vco2 + direc2)
			if hit1[2] == -1 or hit2[2] == -1:
				vco = ((v.co * self.matrixT + self.obT.location) - self.obF.location) * self.matrixF
				hit = self.obF.ray_cast(vco, vco + direc1)
				if hit[2] != -1:
					v.select = True
					self.selverts.append(v)





	def init_selproject(self, context):

		self.obhide = None
		# main operation
		self.scn = context.scene
		self.region = context.region
		self.rv3d = context.space_data.region_3d
		self.oldobjlist = list(self.scn.objects)
		self.oldobj = context.active_object
		self.oldmode = self.oldobj.mode
		mesh = self.oldobj.data

		if self.scn.UseSel and context.mode == 'EDIT_MESH':
			self.obhide = context.active_object
			me = self.obhide.data
			bmundo = bmesh.new()
			bmundo.from_mesh(me)
			objlist = []
			for obj in self.scn.objects:
				objlist.append(obj)
			bpy.ops.mesh.separate(type = 'SELECTED')
			for obj in self.scn.objects:
				if not(obj in objlist):
					self.obF = obj
			bmundo.to_mesh(me)
			bmundo.free()
			self.obhide.hide = True
		else:
			self.obF = bpy.data.objects.get(self.scn.FromObject)
		if context.mode == 'EDIT_MESH':
			bpy.ops.object.editmode_toggle()
		self.obF.select = True
		self.scn.objects.active = self.obF
		self.originobF = self.obF.location
		bpy.ops.object.origin_set(type = 'ORIGIN_GEOMETRY')
		self.meF = self.obF.to_mesh(self.scn, 1, 'PREVIEW')
		self.bmF = bmesh.new()
		self.bmF.from_mesh(self.meF)

		self.obT = bpy.data.objects.get(self.scn.ToObject)
		self.obT.select = True
		self.scn.objects.active = self.obT
		self.originobT = self.obT.location
		bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
		self.meT = self.obT.data
		self.bmT = bmesh.new()
		self.bmT.from_mesh(self.meT)

		self.vsellist = []
		for v in self.bmT.verts:
			if v.select:
				self.vsellist.append(v)
		self.esellist = []
		for e in self.bmT.edges:
			if e.select:
				self.esellist.append(e)
		self.fsellist = []
		for f in self.bmT.faces:
			if f.select:
				self.fsellist.append(f)

		bpy.ops.object.add(type='EMPTY', location=(self.obF.location + self.obT.location) / 2)
		self.empt = context.active_object
		self.empt.name = "SelProject_dir_empty"

		self.selverts = []


	def redraw(self):

		if started:
			self.checksel()
			glColor3f(1.0, 1.0, 0)
			for v in self.selverts:
				glBegin(GL_QUADS)
				x, y = self.getscreencoords(v.co)
				glVertex2f(x-2, y-2)
				glVertex2f(x-2, y+2)
				glVertex2f(x+2, y+2)
				glVertex2f(x+2, y-2)
				glEnd()
コード例 #49
0
def do_import(path, DELETE_TOP_BONE=True):
	# limits
	MAX_NUMMESHES = 1000
	MAX_NUMVERTS = 100000
	MAX_NUMNORMALS = 100000
	MAX_NUMTRIS = 100000
	MAX_NUMMATS = 16
	MAX_NUMBONES = 1000
	MAX_NUMPOSKEYS = 1000
	MAX_NUMROTKEYS = 1000

	# get scene
	scn = bpy.context.scene
	if scn==None:
		return "No scene to import to!"

	# open the file
	try:
		file = open(path, 'r')
	except IOError:
		return "Failed to open the file!"
	
	try:
		if not path.endswith(".nb2"):
			raise IOError
	except IOError:
		return "Must be an nb2 file!"
		
	# Read frame info
	try:
		lines = getNextLine(file).split()
		if len(lines) != 2 or lines[0] != "Frames:":
			raise ValueError
		lines = getNextLine(file).split()
		if len(lines) != 2 or lines[0] != "Frame:":
			raise ValueError
	except ValueError:
		return "Frame information is invalid!"

	# Create the mesh
	meshName = "Mesh Object"
	
	# Before adding any meshes or armatures go into Object mode.
	if bpy.ops.object.mode_set.poll():
		bpy.ops.object.mode_set(mode='OBJECT')

	# read the number of meshes
	try:
		lines = getNextLine(file).split()
		if len(lines)!=2 or lines[0]!="Meshes:":
			raise ValueError
		numMeshes = int(lines[1])
		if numMeshes < 0 or numMeshes > MAX_NUMMESHES:
			raise ValueError
	except ValueError:
		return "Number of meshes is invalid!"

	# read meshes
	boneIds = [[],[],[],[]]
	boneWeights = [[],[],[],[]]
	meshVertexGroups = {}
	vCount = 0
	
	meshes = []
	meshObjects = []
	
	for i in range(numMeshes):
		# read name, flags and material
		try:
			lines = re.findall(r'\".*\"|[^ ]+', getNextLine(file))
			if len(lines)!=3:
				raise ValueError
			meshName = lines[0]
			meshName = meshName[1:-1]
			print ("processing mesh name:%s..." % meshName)
			material = int(lines[2])
		except ValueError:
			return "Name, flags or material in mesh " + str(i+1) + " are invalid!"
		
		meshes.append(bpy.data.meshes.new(meshName))
		meshObjects.append(bpy.data.objects.new(meshName + "Ob", meshes[i]))
		scn.objects.link(meshObjects[i])
		
		# read the number of vertices
		try:
			numVerts = int(getNextLine(file))
			if numVerts < 0 or numVerts > MAX_NUMVERTS:
				raise ValueError
		except ValueError:
			return "Number of vertices in mesh " + str(i+1) + " is invalid!"
			
		print ("Number of vertices in mesh:%d" % numVerts)
		
		# read vertices
		coords = []
		uvs = []
		for j in range(numVerts):
			try:
				lines = getNextLine(file).split()
				if len(lines)!=14:
					raise ValueError
				coords.append([float(lines[1]), float(lines[2]), float(lines[3])])
				uvs.append([float(lines[4]), 1-float(lines[5])])
				boneIds[0].append(int(lines[6]))
				boneWeights[0].append(float(lines[7]))
				boneIds[1].append(int(lines[8]))
				boneWeights[1].append(float(lines[9]))
				boneIds[2].append(int(lines[10]))
				boneWeights[2].append(float(lines[11]))
				boneIds[3].append(int(lines[12]))
				boneWeights[3].append(float(lines[13]))
				meshVertexGroups[vCount] = meshName     # uses the long mesh name - may be > 21 chars
				vCount += 1
			except ValueError:
				return "Vertex " + str(j+1) + " in mesh " + str(i+1) + " is invalid!"
		
		meshes[i].vertices.add(len(coords))
		meshes[i].vertices.foreach_set("co", unpack_list(coords))
		
		# read number of normals
		try:
			numNormals = int(getNextLine(file))
			if numNormals < 0 or numNormals > MAX_NUMNORMALS:
				raise ValueError
		except ValueError:
			return "Number of normals in mesh " + str(i+1) + " is invalid!"

		print ("Number of normals in mesh:%d" % numNormals)
			
		# read normals
		normals = []
		for j in range(numNormals):
			try:
				lines = getNextLine(file).split()
				if len(lines)!=3:
					raise ValueError
				normals.append([float(lines[0]), float(lines[1]), float(lines[2])])
			except ValueError:
				return "Normal " + str(j+1) + " in mesh " + str(i+1) + " is invalid!"

		# read the number of triangles
		try:
			numTris = int(getNextLine(file))
			if numTris < 0 or numTris > MAX_NUMTRIS:
				raise ValueError
		except ValueError:
			return "Number of triangles in mesh " + str(i+1) + " is invalid!"

		print ("Number of triangles in mesh:%d" % numTris)
			
		# read triangles
		faces = []
		for j in range(numTris):
			# read the triangle
			try:
				lines = getNextLine(file).split()
				if len(lines) != 8:
					raise ValueError
				v1 = int(lines[1])
				v2 = int(lines[2])
				v3 = int(lines[3])
				
				faces.append([v1,v2,v3,0])
			except ValueError:
				return "Triangle " + str(j+1) + " in mesh " + str(i+1) + " is invalid!"
		
		meshes[i].tessfaces.add(len(faces))
		for fi, fpol in enumerate(faces):
			vlen = len(fpol)
			if vlen == 3 or vlen == 4:
				for v in range(vlen):
					meshes[i].tessfaces[fi].vertices_raw[v]= fpol[v]
		
		# set texture coordinates and material
		meshes[i].tessface_uv_textures.new()
		for j, face in enumerate(meshes[i].tessfaces):
			face_uv = meshes[i].tessface_uv_textures[0].data[j]
			
			face_uv.uv1 = Vector(uvs[face.vertices[0]]);
			face_uv.uv2 = Vector(uvs[face.vertices[1]]);
			face_uv.uv3 = Vector(uvs[face.vertices[2]]);
			
			if material >= 0:
				face.material_index = material
				
	for mesh in meshes:
		mesh.update()
	
	# read the number of materials
	try:
		lines = getNextLine(file).split()
		if len(lines)!=2 or lines[0]!="Materials:":
			raise ValueError
		numMats = int(lines[1])
		if numMats < 0 or numMats > MAX_NUMMATS:
			raise ValueError
	except ValueError:
		return "Number of materials is invalid!"

	# read the materials
	for i in range(numMats):
			# read name
			name = getNextLine(file)[1:-1]

			# create the material
			#mat = Blender.Material.New(name)
			#mesh.materials += [mat]

			# read ambient color
			try:
				lines = getNextLine(file).split()
				if len(lines)!=4:
					raise ValueError
			except ValueError:
				return "Ambient color in material " + str(i+1) + " is invalid!"

			# read diffuse color
			try:
				lines = getNextLine(file).split()
				if len(lines)!=4:
					raise ValueError
			except ValueError:
				return "Diffuse color in material " + str(i+1) + " is invalid!"

			# read specular color
			try:
				lines = getNextLine(file).split()
				if len(lines)!=4:
					raise ValueError
			except ValueError:
				return "Specular color in material " + str(i+1) + " is invalid!"

			# read emissive color
			try:
				lines = getNextLine(file).split()
				if len(lines)!=4:
					raise ValueError
			except ValueError:
				return "Emissive color in material " + str(i+1) + " is invalid!"

			# read shininess
			try:
				shi = float(getNextLine(file))
			except ValueError:
				return "Shininess in material " + str(i+1) + " is invalid!"

			# read transparency
			try:
				alpha = float(getNextLine(file))
			except ValueError:
				return "Transparency in material " + str(i+1) + " is invalid!"

			# read texturemap
			texturemap = getNextLine(file)[1:-1]
			alphamap = getNextLine(file)[1:-1]

	# read the number of bones
	try:
		lines = getNextLine(file).split()
		if len(lines)!=2 or lines[0]!="Bones:":
			raise ValueError
		numBones = int(lines[1])
		if numBones < 0 or numBones > MAX_NUMBONES:
			raise ValueError
	except:
		return "Number of bones is invalid!"

	# create the armature
	armature = None
	armOb = None
	
	print ("numBones:")
	
	numBones
	if numBones > 0:
		armature = bpy.data.armatures.new("Armature")
		armOb = bpy.data.objects.new("ArmatureObject", armature)
		armature.draw_type = 'STICK'
		scn.objects.link(armOb)
		scn.objects.active = armOb
		
	# read bones
	posKeys = {}
	rotKeys = {}
	boneNames = []
	bpy.ops.object.editmode_toggle()
	bpy.types.EditBone.rot_matrix = bpy.props.FloatVectorProperty(name="Rot Matrix", size=9)

	for i in range(numBones):
		# read name
		fullName = getNextLine(file)[1:-1]
		boneNames.append(fullName)
		bone = armature.edit_bones.new(fullName)
		
		# read parent
		parentBoneName = getNextLine(file)[1:-1]
		if len(parentBoneName) > 0:
			bone.parent = armature.bones.data.edit_bones[parentBoneName]

		# read position and rotation
		try:
			line = getNextLine(file)
			lines = line.split()
			if not (len(lines) == 8 or len(lines) == 24):
				raise ValueError
			pos = [float(lines[1]), float(lines[2]), float(lines[3])]
			quat = [float(lines[4]), float(lines[5]), float(lines[6]), float(lines[7])]
			#print 'Read bone: %s' % line
		except ValueError:
			return "Invalid position or orientation in a bone!"
		
		# # Granny Rotation Quaternions are stored X,Y,Z,W but Blender uses W,X,Y,Z
		quaternion = Quaternion((quat[3], quat[0], quat[1], quat[2])) 
		rotMatrix = quaternion.to_matrix() 
		rotMatrix.transpose() # Need to transpose to get same behaviour as 2.49 script
		
		print ("Bone Data")
		print (fullName)
		print (pos)
		print (rotMatrix)
		
		boneLength = 3
		# set position and orientation
		if bone.parent:
			bone_parent_matrix = Matrix([[bone.parent.rot_matrix[0], bone.parent.rot_matrix[1], bone.parent.rot_matrix[2]],
										[bone.parent.rot_matrix[3], bone.parent.rot_matrix[4], bone.parent.rot_matrix[5]],
										[bone.parent.rot_matrix[6], bone.parent.rot_matrix[7], bone.parent.rot_matrix[8]]])
			bone.head =  Vector(pos) * bone_parent_matrix + bone.parent.head
			bone.tail = bone.head + Vector([boneLength,0,0]) 
			tempM = rotMatrix * bone_parent_matrix
			bone.rot_matrix = [tempM[0][0], tempM[0][1], tempM[0][2], 
								tempM[1][0], tempM[1][1], tempM[1][2],
								tempM[2][0], tempM[2][1], tempM[2][2]]
			bone.matrix = Matrix([[-bone.rot_matrix[3], bone.rot_matrix[0], bone.rot_matrix[6], bone.head[0]],
								 [-bone.rot_matrix[4], bone.rot_matrix[1], bone.rot_matrix[7], bone.head[1]], 
								 [-bone.rot_matrix[5], bone.rot_matrix[2], bone.rot_matrix[8], bone.head[2]], 
								 [0, 0, 0, 1]])
		else:
			bone.head = Vector(pos)
			bone.tail = bone.head + Vector([boneLength,0,0])
			bone.rot_matrix = [rotMatrix[0][0], rotMatrix[0][1], rotMatrix[0][2], 
								rotMatrix[1][0], rotMatrix[1][1], rotMatrix[1][2],
								rotMatrix[2][0], rotMatrix[2][1], rotMatrix[2][2]]
			bone.matrix = Matrix([[-bone.rot_matrix[3], bone.rot_matrix[0], bone.rot_matrix[6], bone.head[0]],
								 [-bone.rot_matrix[4], bone.rot_matrix[1], bone.rot_matrix[7], bone.head[1]], 
								 [-bone.rot_matrix[5], bone.rot_matrix[2], bone.rot_matrix[8], bone.head[2]], 
								 [0, 0, 0, 1]])
			
		print (bone.rot_matrix[0], bone.rot_matrix[1], bone.rot_matrix[2])
		print (bone.rot_matrix[3], bone.rot_matrix[4], bone.rot_matrix[5])
		print (bone.rot_matrix[6], bone.rot_matrix[7], bone.rot_matrix[8])
		print (bone.head)
		print (bone.tail)
		print ("bone roll")
		print (bone.roll)

		# read the number of position key frames
		try:
			numPosKeys = int(getNextLine(file))
			if numPosKeys < 0 or numPosKeys > MAX_NUMPOSKEYS:
				raise ValueError
		except ValueError:
			return "Invalid number of position key frames!"

		# read position key frames
		posKeys[name] = []
		for j in range(numPosKeys):
			# read time and position
			try:
				lines = getNextLine(file).split()
				if len(lines) != 4:
					raise ValueError
			except ValueError:
				return "Invalid position key frame!"
			
		# read the number of rotation key frames
		try:
			numRotKeys = int(getNextLine(file))
			if numRotKeys < 0 or numRotKeys > MAX_NUMROTKEYS:
				raise ValueError
		except ValueError:
			return "Invalid number of rotation key frames!"

		# read rotation key frames
		rotKeys[name] = []
		for j in range(numRotKeys):
			# read time and rotation
			try:
				lines = getNextLine(file).split()
				if len(lines) != 4:
					raise ValueError
			except ValueError:
				return "Invalid rotation key frame!"

	# Roll Fix
	#for bone in armature.edit_bones:
	#	if bone.parent:
	#		roll = bone.roll
	#		bone.roll = roll - math.radians(90.0)
	
	# Create Vertex Groups
	vi = 0
	for meshOb in meshObjects:
		mesh = meshOb.data
		for mvi, vertex in enumerate(mesh.vertices):
			for bi in range(numBones):
				for j in range(4):
					if bi==boneIds[j][vi]:
						name = boneNames[bi] 
						if not meshOb.vertex_groups.get(name):
							meshOb.vertex_groups.new(name)
						grp = meshOb.vertex_groups.get(name)
						grp.add([mvi], boneWeights[j][vi], 'ADD')
			vi = vi + 1
		
		# Give mesh object an armature modifier, using vertex groups but
		# not envelopes
		mod = meshOb.modifiers.new('mod_' + mesh.name, 'ARMATURE')
		mod.object = armOb
		mod.use_bone_envelopes = False
		mod.use_vertex_groups = True

	if DELETE_TOP_BONE:
		# Adjust object names, remove top bone for Civ V - Deliverator
		#armature.makeEditable()
		
		bone = armature.bones.data.edit_bones[boneNames[0]]
		while not bone.parent is None:
			bone = bone.parent
		
		print ('Found World Bone: %s' % bone.name)
		
		name = bone.name
		armOb.name = name
		
		# Delete top bone unless that would leave zero bones
		if (len(armature.bones.data.edit_bones) > 1):
			bpy.ops.object.select_pattern(pattern=name)
			bpy.ops.armature.delete()
			#del armature.bones.data.edit_bones[name]
			
		# armature.update()
		
	bpy.ops.object.editmode_toggle()
	bpy.ops.object.editmode_toggle()
	bpy.ops.object.editmode_toggle()
	
	# The import was a success!
	return ""