Skip to content

Instantly share code, notes, and snippets.

@plasmax
Created September 30, 2018 20:17
Show Gist options
  • Save plasmax/6f5686b1f3ba72016e3f42e3ac76f8b1 to your computer and use it in GitHub Desktop.
Save plasmax/6f5686b1f3ba72016e3f42e3ac76f8b1 to your computer and use it in GitHub Desktop.
Small panel that enables WASD (+QE and F) control for Foundy's NUKE cameras
import math
import nuke
try:
from PySide2 import QtWidgets, QtCore
except ImportError:
from PySide import QtGui as QtWidgets
from PySide import QtCore
def median(lst):
n = len(lst)
if n < 1:
return None
if n % 2 == 1:
return sorted(lst)[n//2]
else:
return sum(sorted(lst)[n//2-1:n//2+1])/2.0
def jump(cam):
viewer = nuke.activeViewer()
nodes = viewer.getGeometryNodes()
points = []
for node in nodes:
sel = node['geo_select']
geolist = sel.getGeometry()
sellist = sel.getSelection()
for geo, selobj in zip(geolist, sellist):
obj_transform = geo.transform()
for p, v in zip(geo.points(), selobj):
if v:
world_p = obj_transform * nuke.math.Vector4(p.x, p.y, p.z, 1)
points.append( (world_p.x, world_p.y, world_p.z) )
if len(points) > 1:
medX = median([x for x,y,z in points])
medY = median([y for x,y,z in points])
medZ = median([z for x,y,z in points])
elif len(points) == 1:
medX, medY, medZ = points[0]
else:
return
"""
ax = nuke.createNode('Axis')
ax['translate'].setValue([medX, medY, medZ])
"""
cam['translate'].setValue([medX, medY, medZ])
wm = cam['world_matrix']
curmtx = wm.valueAt(nuke.frame())
mtx = nuke.math.Matrix4()
mtx.makeIdentity()
for i, n in enumerate(curmtx):
mtx[i] = n
mtx.transpose()
# TODO: set zoom level (z translate) in accordance with max distance between
# selected vertices
mtx.translate(0, 0, 5)
t = mtx.translation()
cam.knob("translate").setValue(t[0], 0)
cam.knob("translate").setValue(t[1], 1)
cam.knob("translate").setValue(t[2], 2)
def move(cam, x=0.0, y=0.0, z=0.0, speed=1):
wm = cam['world_matrix']
curmtx = wm.valueAt(nuke.frame())
mtx = nuke.math.Matrix4()
mtx.makeIdentity()
for i, n in enumerate(curmtx):
mtx[i] = n
mtx.transpose()
mtx.translate(x*speed, y*speed, z*speed)
t = mtx.translation()
cam.knob("translate").setValue(t[0], 0)
cam.knob("translate").setValue(t[1], 1)
cam.knob("translate").setValue(t[2], 2)
def turn(cam, x=0.0, y=0.0):
cam.knob("rotate").setValue(-y, 0)
cam.knob("rotate").setValue(-x, 1)
def drive(key, node, speed=10):
if key == QtCore.Qt.Key_W:
move(node, z=-1, speed=speed)
if key == QtCore.Qt.Key_A:
move(node, x=-1, speed=speed)
if key == QtCore.Qt.Key_S:
move(node, z=1, speed=speed)
if key == QtCore.Qt.Key_D:
move(node, x=1, speed=speed)
if key == QtCore.Qt.Key_Q:
move(node, y=-1, speed=speed)
if key == QtCore.Qt.Key_E:
move(node, y=1, speed=speed)
class Driver(QtWidgets.QWidget):
"""
^
< >
v
Labels capturing keys on Camera Widget. Highlight them when pressed!
"""
key_list = [
QtCore.Qt.Key_W,
QtCore.Qt.Key_A,
QtCore.Qt.Key_S,
QtCore.Qt.Key_D,
QtCore.Qt.Key_Q,
QtCore.Qt.Key_E,
]
def __init__(self):
super(Driver, self).__init__()
self._layout = QtWidgets.QGridLayout(self)
self.setLayout(self._layout)
self.fwd = QtWidgets.QLabel('^')
self.lft = QtWidgets.QLabel('<')
self.rgt = QtWidgets.QLabel('>')
self.bak = QtWidgets.QLabel('v')
for l in self.fwd, self.bak, self.lft, self.rgt:
l.setAlignment(QtCore.Qt.AlignCenter)
self.layout().addWidget(self.fwd, 0, 1)
self.layout().addWidget(self.lft, 1, 0)
self.layout().addWidget(self.rgt, 1, 2)
self.layout().addWidget(self.bak, 2, 1)
self.pressed_list = set([])
def mousePressEvent(self, event):
self.origin = {}
self.origin['self'] = event.pos()
for node in nuke.selectedNodes():
if not node.knob('world_matrix'):
continue
x,y,z = node['rotate'].value()
self.origin[node.fullName()] = (-y,-x)
super(Driver, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
p = event.pos()
v = p - self.origin['self']
x,y = v.x(), v.y()
for node in nuke.selectedNodes():
if not node.knob('world_matrix'):
continue
nx, ny = self.origin[node.fullName()]
nx += x
ny += y
turn(node, x=nx, y=ny)
super(Driver, self).mouseMoveEvent(event)
def keyReleaseEvent(self, event):
key = event.key()
try:
self.pressed_list.remove(key)
except KeyError:
pass
if key in self.key_list:
for l in self.fwd, self.bak, self.lft, self.rgt:
l.setStyleSheet(None)
super(Driver, self).keyReleaseEvent(event)
def keyPressEvent(self, event):
key = event.key()
if key in self.key_list:
self.pressed_list.add(key)
styl = 'background:rgb(48,95,177)'
for node in nuke.selectedNodes():
if not node.knob('world_matrix'):
continue
for key in self.pressed_list:
drive(key, node)
if key == QtCore.Qt.Key_W:
self.fwd.setStyleSheet(styl)
if key == QtCore.Qt.Key_A:
self.lft.setStyleSheet(styl)
if key == QtCore.Qt.Key_S:
self.bak.setStyleSheet(styl)
if key == QtCore.Qt.Key_D:
self.rgt.setStyleSheet(styl)
if key == QtCore.Qt.Key_F:
jump(node)
super(Driver, self).keyPressEvent(event)
def makeUI(self):
return self
def valueChanged(self, value):
print value
d = Driver()
d.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment