注意:代码是基于blender的,所以Quaternion及坐标系是基于blender的。
import csv
import os
import bpy
import mathutils
from mathutils import *
import math
from enum import Enum
import bmesh
def lookRotation(forward, upward=Vector((0, 1, 0))):
"""模拟unity版的LookRotation
Args:
forward (Vector): 前向量
upward (Vector, optional): 朝上向量. 因为模型是躺在y轴的,所以默认upward是(0, 1, 0).
Returns:
Quaternion: 旋转值
"""
upward = upward.normalized()
forward = forward.normalized()
right = forward.cross(upward).normalized()
up = right.cross(forward)
m00 = right.x
m01 = right.y
m02 = right.z
m10 = forward.x
m11 = forward.y
m12 = forward.z
m20 = up.x
m21 = up.y
m22 = up.z
num8 = m00 + m11 + m22
if num8 > 0:
num = math.sqrt(num8 + 1)
w = num * 0.5
num = 0.5 / num
x = (m12 - m21) * num
y = (m20 - m02) * num
z = (m01 - m10) * num
return Quaternion((w, x, y, z))
if m00 >= m11 and m00 >= m22:
num7 = math.sqrt(1 + m00 - m11 - m22)
num4 = 0.5 / num7
x = 0.5 * num7
y = (m01 + m10) * num4
z = (m02 + m20) * num4
w = (m12 - m21) * num4
return Quaternion((w, x, y, z))
if m11 > m22:
num6 = math.sqrt(1 + m11 - m00 - m22)
num3 = 0.5 / num6
x = (m10 + m01) * num3
y = 0.5 * num6
z = (m21 + m12) * num3
w = (m20 - m02) * num3
return Quaternion((w, x, y, z))
num5 = math.sqrt(1 + m22 - m00 - m11)
num2 = 0.5 / num5
x = (m20 + m02) * num2
y = (m21 + m12) * num2
z = 0.5 * num5
w = (m01 - m10) * num2
return Quaternion((w, x, y, z)).copy()