Пример #1
0
    def process(self):
        if not self.outputs['Quaternions'].is_linked:
            return

        inputs = self.inputs

        quaternion_list = []

        if self.mode == "WXYZ":
            I = [inputs[n].sv_get()[0] for n in "WXYZ"]
            params = match_long_repeat(I)
            for wxyz in zip(*params):
                q = Quaternion(wxyz)
                if self.normalize:
                    q.normalize()
                quaternion_list.append(q)

        elif self.mode == "SCALARVECTOR":
            I = [inputs[n].sv_get()[0] for n in ["Scalar", "Vector"]]
            params = match_long_repeat(I)
            for scalar, vector in zip(*params):
                q = Quaternion([scalar, *vector])
                if self.normalize:
                    q.normalize()
                quaternion_list.append(q)

        elif self.mode == "EULER":
            I = [inputs["Angle " + n].sv_get()[0] for n in "XYZ"]
            params = match_long_repeat(I)
            # conversion factor from the current angle units to radians
            au = self.radians_conversion_factor()
            for angleX, angleY, angleZ in zip(*params):
                euler = Euler((angleX * au, angleY * au, angleZ * au),
                              self.euler_order)
                q = euler.to_quaternion()
                if self.normalize:
                    q.normalize()
                quaternion_list.append(q)

        elif self.mode == "AXISANGLE":
            I = [inputs[n].sv_get()[0] for n in ["Axis", "Angle"]]
            params = match_long_repeat(I)
            # conversion factor from the current angle units to radians
            au = self.radians_conversion_factor()
            for axis, angle in zip(*params):
                q = Quaternion(axis, angle * au)
                if self.normalize:
                    q.normalize()
                quaternion_list.append(q)

        elif self.mode == "MATRIX":
            input_M = inputs["Matrix"].sv_get(default=id_mat)
            for m in input_M:
                q = Matrix(m).to_quaternion()
                if self.normalize:
                    q.normalize()
                quaternion_list.append(q)

        self.outputs['Quaternions'].sv_set(quaternion_list)
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()
Пример #3
0
def transform_rot(keyframes, matrix):
    for frame in keyframes.keys():
        axis, angle = Quaternion(keyframes[frame]).to_axis_angle()

        axis.rotate(matrix)
        quat = Quaternion(axis, angle)
        quat.normalize()

        keyframes[frame] = tuple(quat)
Пример #4
0
    def process(self):
        if not self.outputs['Quaternions'].is_linked:
            return

        inputs = self.inputs

        quaternionList = []

        if self.mode == "WXYZ":
            I = [inputs[n].sv_get()[0] for n in "WXYZ"]
            params = match_long_repeat(I)
            for wxyz in zip(*params):
                q = Quaternion(wxyz)
                if self.normalize:
                    q.normalize()
                quaternionList.append(q)

        elif self.mode == "SCALARVECTOR":
            I = [inputs[n].sv_get()[0] for n in ["Scalar", "Vector"]]
            params = match_long_repeat(I)
            for scalar, vector in zip(*params):
                q = Quaternion([scalar, *vector])
                if self.normalize:
                    q.normalize()
                quaternionList.append(q)

        elif self.mode == "EULER":
            I = [inputs["Angle " + n].sv_get()[0] for n in "XYZ"]
            params = match_long_repeat(I)
            au = angleConversion[self.angleUnits]
            for angleX, angleY, angleZ in zip(*params):
                euler = Euler((angleX * au, angleY * au, angleZ * au), self.eulerOrder)
                q = euler.to_quaternion()
                if self.normalize:
                    q.normalize()
                quaternionList.append(q)

        elif self.mode == "AXISANGLE":
            I = [inputs[n].sv_get()[0] for n in ["Axis", "Angle"]]
            params = match_long_repeat(I)
            au = angleConversion[self.angleUnits]
            for axis, angle in zip(*params):
                q = Quaternion(axis, angle * au)
                if self.normalize:
                    q.normalize()
                quaternionList.append(q)

        elif self.mode == "MATRIX":
            input_M = inputs["Matrix"].sv_get(default=idMat)
            for m in input_M:
                q = Matrix(m).to_quaternion()
                if self.normalize:
                    q.normalize()
                quaternionList.append(q)

        self.outputs['Quaternions'].sv_set([quaternionList])
Пример #5
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()
def quaternion_from_two_vectors(dir, up):
    from io_scene_forsaken import forsaken_utils
    
    vU1 = dir
    vU2 = up
    
    vU1.normalize()
    vU2.normalize()
    
    vAxis = vU1.cross(vU2)

    fAxisMag = forsaken_utils.min(math.sqrt(vAxis.x*vAxis.x+vAxis.y*vAxis.y+vAxis.z*vAxis.z), 1.0)
    fTheta = math.asin(fAxisMag)
    fTheta_C = math.pi - fTheta
    
    if vU1.dot(vU2) < 0.0:
        fTheta = fTheta_C
        fTheta_C = math.pi - fTheta
        
    fEpsilon = 1e-7

    if fTheta < fEpsilon:
        qRot = Quaternion()
        qRot.x = 0.0
        qRot.y = 0.0
        qRot.z = 0.0
        qRot.w = 1.0
        return qRot
        
    if fTheta_C < fEpsilon:
        vCP = vU1.cross(Vector((1.0, 0.0, 0.0)))
        
        fOpposite = vCP.x*vCP.x+vCP.y*vCP.y+vCP.z*vCP.z
        
        if fOpposite >= fEpsilon:
            vAxis = vCP
        else:
            vAxis = Vector((0.0, 1.0, 0.0))
            
    vAxis.normalize()
    
    qRot = Quaternion()
    s = math.sin(fTheta * 0.5)
    c = math.cos(fTheta * 0.5)
    
    qRot.x = vAxis.x * s
    qRot.y = vAxis.y * s
    qRot.z = vAxis.z * s
    qRot.w = c
    
    qRot.normalize()
    return qRot
Пример #7
0
def rotation_to(a, b):
    """Calculates shortest Quaternion from Vector a to Vector b"""
    # a - up vector
    # b - direction to point to

    # http://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another
    # https://github.com/toji/gl-matrix/blob/f0583ef53e94bc7e78b78c8a24f09ed5e2f7a20c/src/gl-matrix/quat.js#L54

    a = a.normalized()
    b = b.normalized()
    q = Quaternion()

    tmpvec3 = Vector()
    xUnitVec3 = Vector((1, 0, 0))
    yUnitVec3 = Vector((0, 1, 0))

    dot = a.dot(b)
    if (dot < -0.999999):
        # tmpvec3 = cross(xUnitVec3, a)
        tmpvec3 = xUnitVec3.cross(a)
        if (tmpvec3.length < 0.000001):
            tmpvec3 = yUnitVec3.cross(a)
        tmpvec3.normalize()
        # q = Quaternion(tmpvec3, Math.PI)
        q = Quaternion(tmpvec3, math.pi)
    elif (dot > 0.999999):
        q.x = 0
        q.y = 0
        q.z = 0
        q.w = 1
    else:
        tmpvec3 = a.cross(b)
        q.x = tmpvec3[0]
        q.y = tmpvec3[1]
        q.z = tmpvec3[2]
        q.w = 1 + dot
        q.normalize()
    return q
Пример #8
0
    def process(self):
        if not self.outputs['Quaternions'].is_linked:
            return

        inputs = self.inputs

        quaternionList = []

        if self.mode == "WXYZ":
            I = [inputs[n].sv_get()[0] for n in "WXYZ"]
            params = match_long_repeat(I)
            for wxyz in zip(*params):
                q = Quaternion(wxyz)
                if self.normalize:
                    q.normalize()
                quaternionList.append(q)

        elif self.mode == "EULER":
            I = [inputs["Angle " + n].sv_get()[0] for n in "XYZ"]
            params = match_long_repeat(I)
            au = angleConversion[self.angleUnits]
            for angleX, angleY, angleZ in zip(*params):
                euler = Euler((angleX * au, angleY * au, angleZ * au),
                              self.eulerOrder)
                q = euler.to_quaternion()
                if self.normalize:
                    q.normalize()
                quaternionList.append(q)

        elif self.mode == "AXISANGLE":
            I = [inputs[n].sv_get()[0] for n in {"Axis", "Angle"}]
            params = match_long_repeat(I)
            au = angleConversion[self.angleUnits]
            for axis, angle in zip(*params):
                q = Quaternion(axis, angle * au)
                if self.normalize:
                    q.normalize()
                quaternionList.append(q)

        elif self.mode == "MATRIX":
            input_M = inputs["Matrix"].sv_get(default=idMat)
            for m in input_M:
                q = Matrix(m).to_quaternion()
                if self.normalize:
                    q.normalize()
                quaternionList.append(q)

        self.outputs['Quaternions'].sv_set([quaternionList])
Пример #9
0
def _arc_segment(v_1, v_2):
	ELorigin = bpy.context.scene.objects['ELorigin']
	ELground = bpy.context.scene.objects['ELground']

	v = v_2 - v_1
	d = v.length

	ELorigin.location = Vector((0, 0, 0))
	ELground.location = Vector((0, 0, -d))

	v_L = ELground.location - ELorigin.location

	q = Quaternion()
	c = Vector.cross(v_L, v)
	q.x = c.x
	q.y = c.y
	q.z = c.z
	q.w = sqrt((v_L.length ** 2) * (v.length ** 2)) + \
		Vector.dot(v_L, v)
	q.normalize()
	euler = q.to_euler()

	bpy.ops.object.runfslg_operator()

	laALL = bpy.context.scene.objects['laALL']
	laALL.name = 'lARC'
	laALL.rotation_euler = euler
	laALL.location = v_1

	bpy.context.active_object.select = False
	laALL.select = True
	bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
	laALL.select = False
	bpy.context.active_object.select = True	

	return laALL
Пример #10
0
def _arc_segment(v_1, v_2):
    ELorigin = bpy.context.scene.objects['ELorigin']
    ELground = bpy.context.scene.objects['ELground']

    v = v_2 - v_1
    d = v.length

    ELorigin.location = Vector((0, 0, 0))
    ELground.location = Vector((0, 0, -d))

    v_L = ELground.location - ELorigin.location

    q = Quaternion()
    c = Vector.cross(v_L, v)
    q.x = c.x
    q.y = c.y
    q.z = c.z
    q.w = sqrt((v_L.length ** 2) * (v.length ** 2)) + \
     Vector.dot(v_L, v)
    q.normalize()
    euler = q.to_euler()

    bpy.ops.object.runfslg_operator()

    laALL = bpy.context.scene.objects['laALL']
    laALL.name = 'lARC'
    laALL.rotation_euler = euler
    laALL.location = v_1

    bpy.context.active_object.select = False
    laALL.select = True
    bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
    laALL.select = False
    bpy.context.active_object.select = True

    return laALL
Пример #11
0
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)
Пример #12
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()
def save(operator, context, filepath=""):
    bpy.ops.object.mode_set(mode='OBJECT')

    poseLib = None
    armature = None
    for object in bpy.data.objects:
        if object.type == 'ARMATURE':
            poseLib = object.pose_library
            armature = object.data
            break
    if poseLib == None or armature == None:
        raise NameError("Cannot export Pose Library %s, there is no armatures" % filepath)
    
    
    numPoses = len(poseLib.groups[0].channels[4].keyframe_points)
    numBones = len(poseLib.groups)
    poseArray = []
    nameArray = []
    
    print("Exporting")
    
    oglBoneArray = []
    oglBoneDirectionArray = []
    
    startNodes = []
    for i in range(0, len(armature.bones)):
        bone = armature.bones[i]
        if bone.parent == None:
            dupIndex = -1
            for j in range(0, len(startNodes)):
                if bone.head[:] == startNodes[j][:]:
                    dupIndex = j
                    break
            if dupIndex == -1:
                baseNode = bone.head_local
                startNodes.append((baseNode.x, baseNode.y, baseNode.z))
                oglBoneArray.append(-1)
        oglBoneArray.append(i)
        boneDirection = bone.tail_local - bone.head_local
        oglBoneDirectionArray.append(boneDirection)
    
    for i in range(0, numPoses):
        nameArray.append(poseLib.pose_markers[i].name)
        boneArray = []
        for j in range(0, len(oglBoneArray)):
            index = oglBoneArray[j]
            q = Quaternion()
            if index == -1:
                q = Quaternion([1, 0, 0, 0])
            else:
                quat = Quaternion([1, 0, 0, 0])
                for k in range(0, 4):
                    quat[k] = poseLib.groups[index].channels[k + 3].keyframe_points[i].co.y
                axisVector = Vector([0, 1, 0])
                boneVector = oglBoneDirectionArray[index]
                quatBetween = getQuatBetweenVectors(boneVector, axisVector)
                q = quatBetween.inverted() * quat * quatBetween
                q.normalize()
            boneArray.append(tuple([q.w, q.x, q.z, -q.y]))
        poseArray.append(boneArray)
    
    print(filepath)
    file = open(filepath, 'w')
    fw = file.write
    
    fw("poslib\n")
    fw("%d %d\n" % (numPoses, len(oglBoneArray)))
    for i in range(0, numPoses):
        fw("n " + nameArray[i] + '\n')
        for j in range(0, len(oglBoneArray)):
            q = poseArray[i][j]
            fw("q %f %f %f %f\n" % (q[0], q[1], q[2], q[3]))
        fw('f\n')
        
    file.close()
    
    print("Finished Exporting")
    
    return {'FINISHED'}
Пример #14
0
    def execute(self, context):
        print("Export", self.properties.filepath)

        

        version = Version()
        model = Model()
        texture = Textures()
        material = Materials()
        geosets = []
        bones = []
        pivotpoints = model.PivotPoints()
        meshcount = 0

        file = open(self.properties.filepath, 'w')
        for obj in bpy.context.scene.objects:
            if obj.type == 'MESH':
                # depsgraph = context.evaluated_depsgraph_get()
                # mesh =  bpy.data.meshes.new_from_object(obj.evaluated_get(depsgraph), preserve_all_data_layers=True, depsgraph=depsgraph)
                mesh = obj.data
                mesh.transform(obj.matrix_world)
                geoset = model.Geoset()
                mesh.calc_loop_triangles()

                armatures = []
                for modifier in obj.modifiers:
                    if modifier.type == 'ARMATURE' and modifier.use_vertex_groups:
                        armatures.append(modifier.object)

                for armature in armatures:
                    loadarmature(armature,bones,pivotpoints)                    
                    
                #     bone_names = set(b.name for b in armature.object.data.bones)

                for vertex in mesh.vertices:
                    geoset.Vertices.append([vertex.co[0]*20,vertex.co[1]*20,vertex.co[2]*20])
                    geoset.Normals.append([vertex.normal[0],vertex.normal[1],vertex.normal[2]])
                    
                    vgroups = sorted(vertex.groups[:], key=lambda x:x.weight, reverse=True)
                    if len(vgroups):
                        group = list(list(filter(lambda b: b.Name == obj.vertex_groups[vg.group].name, bones))[0].ObjectId for vg in vgroups if vg.weight > 0.25)[:3]
                    else:
                        group = [0]
                    if group not in geoset.Groups:
                        geoset.Groups.append(group)
                    
                    geoset.VertexGroup.append(geoset.Groups.index(group))
                for group in geoset.Groups:
                    for g in group:
                        bones[g].GeosetId = meshcount
                geoset.TVertices = [[0.0,0.0]] * len(geoset.Vertices)
                for tri in mesh.loop_triangles:
                    geoset.Faces.append((tri.vertices[0],tri.vertices[1],tri.vertices[2]))
                    for i in range(3):
                        geoset.TVertices[mesh.loops[tri.loops[i]].vertex_index] = [mesh.uv_layers.active.data[tri.loops[i]].uv[0],1 - mesh.uv_layers.active.data[tri.loops[i]].uv[1]]
                geosets.append(geoset)
                meshcount += 1

        version.FormatVersion = 800
        model.Name = "test"
        model.NumGeosets = meshcount
        model.BlendTime = 150
        model.NumBones = len(bones)

        version.write(file)
        model.write(file)
        texture.write(file)
        material.write(file)
        for geoset in geosets:
            geoset.write(file)
        for bone in bones:
            if bone.ParentName:
                bone.Parent = list(filter(lambda b: b.Name == bone.ParentName, bones))[0].ObjectId
            for k,frame in bone.Translation.items():
                bone.Translation[k] = list(armature.matrix_world @ Vector(frame))
            for k,frame in bone.Rotation.items():
                axis, angle = Quaternion(frame).to_axis_angle()
                axis.rotate(armature.matrix_world)
                quat = Quaternion(axis, angle)
                quat.normalize()
                bone.Rotation[k] = [quat[1],quat[2],quat[3],quat[0]]
            bone.write(file)
        pivotpoints.write(file)
        return {'FINISHED'}