さて、ray_cast 関数は、開始座標と終了座標の両方が object.ray_cast 内のオブジェクトのローカル座標系にあることを想定しています。これは、グローバル/ワールド座標である a.location および b.location 座標をローカル座標に変換する必要があることを意味します。 .
こちらです:
globalcoordinate = Vector((x, y, z))
localcoordinateforobject = (globalcoordinate - object.location) * object.matrix_world.inverted()
通常は上記のように matrix_world を使用しますが、この回転とスケールが適用されていない (Ctrl-A) 回転/スケールされたオブジェクトでは機能しません。そこで、多くのアドオンで使用するこのコードを共有します。
def adapt(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
quat = Quaternion([w, x, y, z])
matrix = 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
オブジェクト「selobj」の「matrix」と呼ばれる右変換行列を返します。上記のコード例の object.matrix_world の代わりに使用してください。