使用 Python 在 maya 中使用 distanceDimension 进行旋转
Getting rotation with the distanceDimension in maya with Python
我正在制作一个脚本,我可以在其中放置 2 个定位器,并在我制作灯光的 2 个定位器之间。
此时我在视口中单击时可以制作 2 个定位器,并且它会制作具有相同距离和位置的灯光。
(为了获取两个定位器之间的距离,我使用 DistanceDimension 命令)
但我也需要同样的旋转。所以当 loc1 高于 loc2 时我也需要旋转我的灯,但我不知道该怎么做。
有人可以帮我吗?这是视口的屏幕截图:
我的代码:
import maya.cmds as cmds
def dragger_onPress():
pos = cmds.draggerContext(draggerContextName, query = True, anchorPoint
= True)
#make locator for distance
cmds.spaceLocator(name=('DistnaceLoc'))
cmds.move(pos[0],pos[1],pos[2])
if cmds.objExists('DistnaceLoc') and cmds.objExists('DistnaceLoc1'):
posLoc1_X = cmds.getAttr('DistnaceLoc.translateX')
posLoc1_Y = cmds.getAttr('DistnaceLoc.translateY')
posLoc1_Z = cmds.getAttr('DistnaceLoc.translateZ')
posLoc2_X = cmds.getAttr('DistnaceLoc1.translateX')
posLoc2_Y = cmds.getAttr('DistnaceLoc1.translateY')
posLoc2_Z = cmds.getAttr('DistnaceLoc1.translateZ')
Distance = cmds.distanceDimension(startPoint=
[posLoc1_X,posLoc1_Y,posLoc1_Z],endPoint=[posLoc2_X,posLoc2_Y,posLoc2_Z])
DistanceValue = cmds.getAttr(Distance + '.distance')
print(DistanceValue)
averagePosX = (posLoc1_X+posLoc2_X)/2
averagePosY = (posLoc1_Y+posLoc2_Y)/2
averagePosZ = (posLoc1_Z+posLoc2_Z)/2
#create light
lights.append(cmds.shadingNode('aiAreaLight', asLight=True))
cmds.move(averagePosX,averagePosY,averagePosZ)
cmds.scale((DistanceValue/2),0.1,1)
cmds.delete('DistnaceLoc','DistnaceLoc1')
# for getting the mousepoitionw
if (cmds.contextInfo(draggerContextName, exists = True)):
cmds.deleteUI(draggerContextName, toolContext = True )
cmds.draggerContext(draggerContextName, pressCommand = dragger_onPress2,cursor = "crossHair", space="world",snapping=True)
cmds.setToolTo(draggerContextName)
您可能会发现使用动画约束比使用数学更容易做到这一点。您可以将光线点约束到两个定位器,使其具有相同的权重——这将把它放在它们之间的中间位置。然后将其瞄准约束以指向其中一个,其中一个世界为 'side vector' 和一个旋转偏移以防止光线翻转(这是一个区域光,是吗?)
def area_light_between(target1, target2):
lightShape = cmds.createNode('areaLight')
lightXform = cmds.listRelatives(lightShape, p=True)
#You can get the distance manually without creating a distance dimension:
start = cmds.xform(target1, q=True, t=True)
end = cmds.xform(target2, q=True, t=True)
difference = [end[k] - start[k] for k in range(3)]
distance = math.sqrt(difference[0]**2 + difference[1]**2 + difference[2]**2)
cmds.xform(lightXform, s = (distance / 2.0, 0.1, 1))
# constrain the light between the targets
# use the mo=False flag so you don't keep the offset
cmds.pointConstraint(target1, target2,lightXform, mo = False)
# add the aim constraint (your world-up vector may vary)
cmds.aimConstraint(target2, lightXform, worldUpVector = (0,0,1), aimVector=(1,0,0), upVector = (0,0,1), mo = False)
return lightXform
area_light_between('pSphere1', 'pSphere2')
我的场景是 Z-Up 所以我必须指定一个世界向上向量 (0,0,1) -- 如果你使用的是 vanilla Maya Y-up 你的 worldUpVector 将是 (0,1,0 ).与任何目标约束情况一样,如果目标向量太接近向上向量,您将得到翻转——如果您这样做或使用纯数学,您将不得不处理这个问题。
这样做的一个好处是您可以在事后编辑约束以偏移位置或目标,同时保留整体关系。
我正在制作一个脚本,我可以在其中放置 2 个定位器,并在我制作灯光的 2 个定位器之间。
此时我在视口中单击时可以制作 2 个定位器,并且它会制作具有相同距离和位置的灯光。
(为了获取两个定位器之间的距离,我使用 DistanceDimension 命令)
但我也需要同样的旋转。所以当 loc1 高于 loc2 时我也需要旋转我的灯,但我不知道该怎么做。
有人可以帮我吗?这是视口的屏幕截图:
我的代码:
import maya.cmds as cmds
def dragger_onPress():
pos = cmds.draggerContext(draggerContextName, query = True, anchorPoint
= True)
#make locator for distance
cmds.spaceLocator(name=('DistnaceLoc'))
cmds.move(pos[0],pos[1],pos[2])
if cmds.objExists('DistnaceLoc') and cmds.objExists('DistnaceLoc1'):
posLoc1_X = cmds.getAttr('DistnaceLoc.translateX')
posLoc1_Y = cmds.getAttr('DistnaceLoc.translateY')
posLoc1_Z = cmds.getAttr('DistnaceLoc.translateZ')
posLoc2_X = cmds.getAttr('DistnaceLoc1.translateX')
posLoc2_Y = cmds.getAttr('DistnaceLoc1.translateY')
posLoc2_Z = cmds.getAttr('DistnaceLoc1.translateZ')
Distance = cmds.distanceDimension(startPoint=
[posLoc1_X,posLoc1_Y,posLoc1_Z],endPoint=[posLoc2_X,posLoc2_Y,posLoc2_Z])
DistanceValue = cmds.getAttr(Distance + '.distance')
print(DistanceValue)
averagePosX = (posLoc1_X+posLoc2_X)/2
averagePosY = (posLoc1_Y+posLoc2_Y)/2
averagePosZ = (posLoc1_Z+posLoc2_Z)/2
#create light
lights.append(cmds.shadingNode('aiAreaLight', asLight=True))
cmds.move(averagePosX,averagePosY,averagePosZ)
cmds.scale((DistanceValue/2),0.1,1)
cmds.delete('DistnaceLoc','DistnaceLoc1')
# for getting the mousepoitionw
if (cmds.contextInfo(draggerContextName, exists = True)):
cmds.deleteUI(draggerContextName, toolContext = True )
cmds.draggerContext(draggerContextName, pressCommand = dragger_onPress2,cursor = "crossHair", space="world",snapping=True)
cmds.setToolTo(draggerContextName)
您可能会发现使用动画约束比使用数学更容易做到这一点。您可以将光线点约束到两个定位器,使其具有相同的权重——这将把它放在它们之间的中间位置。然后将其瞄准约束以指向其中一个,其中一个世界为 'side vector' 和一个旋转偏移以防止光线翻转(这是一个区域光,是吗?)
def area_light_between(target1, target2):
lightShape = cmds.createNode('areaLight')
lightXform = cmds.listRelatives(lightShape, p=True)
#You can get the distance manually without creating a distance dimension:
start = cmds.xform(target1, q=True, t=True)
end = cmds.xform(target2, q=True, t=True)
difference = [end[k] - start[k] for k in range(3)]
distance = math.sqrt(difference[0]**2 + difference[1]**2 + difference[2]**2)
cmds.xform(lightXform, s = (distance / 2.0, 0.1, 1))
# constrain the light between the targets
# use the mo=False flag so you don't keep the offset
cmds.pointConstraint(target1, target2,lightXform, mo = False)
# add the aim constraint (your world-up vector may vary)
cmds.aimConstraint(target2, lightXform, worldUpVector = (0,0,1), aimVector=(1,0,0), upVector = (0,0,1), mo = False)
return lightXform
area_light_between('pSphere1', 'pSphere2')
我的场景是 Z-Up 所以我必须指定一个世界向上向量 (0,0,1) -- 如果你使用的是 vanilla Maya Y-up 你的 worldUpVector 将是 (0,1,0 ).与任何目标约束情况一样,如果目标向量太接近向上向量,您将得到翻转——如果您这样做或使用纯数学,您将不得不处理这个问题。
这样做的一个好处是您可以在事后编辑约束以偏移位置或目标,同时保留整体关系。