Python 无法使ray_铸入式搅拌机工作
我一直在尝试使用blender进行“视线”类型测试。为此,我想使用光线投射功能(光线投射功能不在blender游戏引擎中)。无论我尝试什么,我都无法让代码正常工作 (假设我有两个对象,a和b) 当我尝试从a射线投射到b射线时,只有在打开blender后第一次使用该功能,并且起点或终点位置中至少有一个位于原点时,我才能得到正确答案。移动一个对象后执行的后续光线投射不会更改结果(如中所示,即使在手动更新场景后,我也会获得与第一次相同的结果)。如果我尝试在起点或终点都不在原点的情况下进行强制转换,则返回null(Vector,Vector,-1) 我注意到其他渲染函数也会发生类似的情况,例如Object.closest\u point\u on\u mesh等。。。有人能帮我吗?下面是我用于光线投射的代码Python 无法使ray_铸入式搅拌机工作,python,blender,Python,Blender,我一直在尝试使用blender进行“视线”类型测试。为此,我想使用光线投射功能(光线投射功能不在blender游戏引擎中)。无论我尝试什么,我都无法让代码正常工作 (假设我有两个对象,a和b) 当我尝试从a射线投射到b射线时,只有在打开blender后第一次使用该功能,并且起点或终点位置中至少有一个位于原点时,我才能得到正确答案。移动一个对象后执行的后续光线投射不会更改结果(如中所示,即使在手动更新场景后,我也会获得与第一次相同的结果)。如果我尝试在起点或终点都不在原点的情况下进行强制转换,则返
import bpy
def main():
a = bpy.data.objects['a']
b = bpy.data.objects['b']
x = a.ray_cast(a.location,b.location)
print(x[0])
main()
#
#好的,光线投射函数希望开始和结束坐标都位于object.ray\u cast中对象的局部坐标系中 这意味着您的a.location和b.location坐标(全局/世界坐标)需要转换为局部坐标 这样:
globalcoordinate = Vector((x, y, z))
localcoordinateforobject = (globalcoordinate - object.location) * object.matrix_world.inverted()
通常情况下,人们会像上面那样使用矩阵_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”返回称为“矩阵”的正确变换矩阵。使用它,而不是上面代码示例中的object.matrix\u world。这将解决您的问题:
def main():
a = bpy.data.objects['a']
b = bpy.data.objects['b']
localA = a.matrix_world.inverted() * a.location
localB = a.matrix_world.inverted() * b.location
print(localA, localB)
(location, normal, index) = a.ray_cast(localA, localB)
print(location, normal, index)
# reselect the originally selected face
if(index > 0):
a.data.polygons[index].select = True
你应该在blender.stackexchange.com上问一下,它真的很好用!在Blender 2.8中,您需要将
*
替换为@
,并将矩阵旋转替换为矩阵()。我还从mathutils导入矩阵导入了