So, I've been scripting with python in maya for a while, but this is my
first foray in to maya api business, so I've cobbled together a handful of
stuff that works to a certain extent and I'm having trouble finding the
next piece...
I'm trying to calculate the camera frustrum values for a camera, which is
working but only for the camera with no transform. I've taking bits and
pieces of code from a plugin that used an MPxLocatorNode to draw with
openGL the camera frustrum as lines using the near and far clipping planes
and the focal length. etc.
I've cobbled together a plugin that gets the necessary info from the camera
and returns the points such as top right near and far and so on, but my
problem is the original plugin would rotate with the camera, but mine only
calculates the info from the camera not with the transorms. I need to
incorporate the cameras world transform matrix, I'm guessing... I'm a total
noob at this and am trying to learn as best I can and need some direction
on how to combine my frustrum data with the rotation of the camera. I've
attached the code, it will run as a plugin. with the mel
createCustomLocator;
can someone give me some hints on how to proceed, I know i'm missing a lot,
but I want to learn?
tl;dr, I need help with getting my calculated frustrum points to rotate
with my camera.
--
You received this message because you are subscribed to the Google Groups
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/python_inside_maya/28dc80f6-e18e-4d92-90f5-4eb2e6921c47%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
import sys
import maya.OpenMaya as OpenMaya
import maya.OpenMayaMPx as OpenMayaMPx
import pymel.core as pm
nodeTypeName = "myCustomLocator"
nodeTypeId = OpenMaya.MTypeId(0x87079)
class myNode(OpenMayaMPx.MPxLocatorNode):
testAttr1 = OpenMaya.MObject()
#horizontalFilmAperture = OpenMaya.MObject()
def __init__(self):
OpenMayaMPx.MPxLocatorNode.__init__(self)
def getCameraAttributeData(self):
thisNode = self.thisMObject()
attributeData = {}
attributeData['horizontalFilmAperture'] = \
OpenMaya.MPlug(thisNode, self.horizontalFilmAperture).asDouble()
attributeData['verticalFilmAperture'] = \
OpenMaya.MPlug(thisNode, self.verticalFilmAperture).asDouble()
attributeData['nearClipPlane'] = \
OpenMaya.MPlug(thisNode, self.nearClipPlane).asDouble()
attributeData['farClipPlane'] = \
OpenMaya.MPlug(thisNode, self.farClipPlane).asDouble()
attributeData['focalLength'] = \
OpenMaya.MPlug(thisNode, self.focalLength).asDouble()
return attributeData
def calculateFrustumCorners(self,aData):
corners = {}
horizontalFov = aData['horizontalFilmAperture'] * 0.5 / ( aData['focalLength'] * 0.03937 )
verticalFov = aData['verticalFilmAperture'] * 0.5 / ( aData['focalLength'] * 0.03937 )
farRight = aData['farClipPlane'] * horizontalFov
farTop = aData['farClipPlane'] * verticalFov
nearRight = aData['nearClipPlane'] * horizontalFov
nearTop = aData['nearClipPlane'] * verticalFov
corners['farTopRight'] = [farRight,farTop,-aData['farClipPlane']]
corners['farTopLeft'] = [-farRight,farTop,-aData['farClipPlane']]
corners['farLowLeft'] = [-farRight,-farTop,-aData['farClipPlane']]
corners['farLowRight'] = [farRight,-farTop,-aData['farClipPlane']]
corners['nearTopRight'] = [nearRight,nearTop,-aData['nearClipPlane']]
corners['nearTopLeft'] = [-nearRight,nearTop,-aData['nearClipPlane']]
corners['nearLowLeft'] = [-nearRight,-nearTop,-aData['nearClipPlane']]
corners['nearLowRight'] = [nearRight,-nearTop,-aData['nearClipPlane']]
return corners
def compute(self, plug, data):
attributeValues = self.getCameraAttributeData()
#print attributeValues
frustumCorners = self.calculateFrustumCorners(attributeValues)
#print frustumCorners
#print frustumCorners["farLowLeft"][0]
#p1 = data.inputValue(frustumCorners["farLowLeft"]).asDouble3()
#p2 = data.inputValue(MeasureNode.pos2).asDouble3()
#mid = ((p1[0]+p2[0])/2, (p1[1]+p2[1])/2, (p1[2]+p2[2])/2)
#d = ((p1[0]-p2[0])**2+(p1[1]-p2[1])**2+(p1[2]-p2[2])**2)**.5
aOutput = data.outputValue(myNode.testAttr1)
aOutput.set3Double(frustumCorners["farLowLeft"][0], frustumCorners["farLowLeft"][1], frustumCorners["farLowLeft"][2])
#bOutput = data.outputValue(MeasureNode.distance)
#bOutput.setFloat(d)
#data.setClean(plug)
#Create the node
def nodeCreator():
return OpenMayaMPx.asMPxPtr(myNode())
#Initialize the node
def nodeInitializer():
nAttr = OpenMaya.MFnNumericAttribute()
myNode.testAttr1 = nAttr.create("testAttr1","ta1", OpenMaya.MFnNumericData.k3Double,0.0)
nAttr.setWritable(True)
nAttr.setStorable(True)
myNode.addAttribute(myNode.testAttr1)
myNode.horizontalFilmAperture = nAttr.create("horizontalFilmAperture", "hfa", OpenMaya.MFnNumericData.kDouble, 1.0)
myNode.addAttribute(myNode.horizontalFilmAperture)
myNode.verticalFilmAperture = nAttr.create("verticalFilmAperture", "vfa", OpenMaya.MFnNumericData.kDouble, 0.5625)
myNode.addAttribute(myNode.verticalFilmAperture)
myNode.nearClipPlane = nAttr.create("nearClipPlane", "ncp", OpenMaya.MFnNumericData.kDouble, 0.01)
myNode.addAttribute(myNode.nearClipPlane)
myNode.farClipPlane = nAttr.create("farClipPlane", "fcp", OpenMaya.MFnNumericData.kDouble, 100.0)
myNode.addAttribute(myNode.farClipPlane)
myNode.focalLength = nAttr.create("focalLength", "fl", OpenMaya.MFnNumericData.kDouble, 35.0)
myNode.addAttribute(myNode.focalLength)
#Custom creation command to connect to camera
class createCustomLocator(OpenMayaMPx.MPxCommand):
@staticmethod
def commandName():
return "createCustomLocator"
@staticmethod
def commandCreator():
return OpenMayaMPx.asMPxPtr( createCustomLocator() )
def findCameraInSelection(self):
selection = pm.ls(sl=True)
assert len(selection)>0, "Nothing is selected. Select a camera"
assert len(selection)<2, "Multiple objects selected. Select camera only"
if pm.nodeType(selection[0])=='transform':
camShapeLst = pm.listRelatives(selection[0], type='camera')
assert len(camShapeLst)>0, "No camera selected"
return (selection[0], camShapeLst[0])
elif pm.nodeType(selection[0])=='camera':
parentTransform = pm.listRelatives(selection[0], parent=True)
return (parentTransform,selection[0])
raise StandardError("No camera is selected")
def isUndoable(self):
return True
def doIt(self, args = OpenMaya.MArgList() ):
self.camera = self.findCameraInSelection()
self.NodeName = self.camera[0].name()+"optimizedOcean"
self.redoIt()
def redoIt(self):
self.frustumNode = pm.createNode('myCustomLocator',name=self.NodeName, parent=self.camera[0])
self.camera[1].horizontalFilmAperture.connect(self.frustumNode.horizontalFilmAperture)
self.camera[1].verticalFilmAperture.connect(self.frustumNode.verticalFilmAperture)
self.camera[1].nearClipPlane.connect(self.frustumNode.nearClipPlane)
self.camera[1].farClipPlane.connect(self.frustumNode.farClipPlane)
self.camera[1].focalLength.connect(self.frustumNode.focalLength)
def undoIt(self):
if self.frustumNode:
pm.delete(self.frustumNode)
self.frustumNode = None
def initializePlugin(obj):
plugin = OpenMayaMPx.MFnPlugin(obj)
try:
plugin.registerNode(nodeTypeName, nodeTypeId, nodeCreator, nodeInitializer, OpenMayaMPx.MPxNode.kLocatorNode)
plugin.registerCommand(createCustomLocator.commandName(), createCustomLocator.commandCreator )
except:
sys.stderr.write( "Failed to register node: %s" % nodeTypeName)
def uninitializePlugin(obj):
plugin = OpenMayaMPx.MFnPlugin(obj)
try:
plugin.deregisterNode(nodeTypeId)
pluginFn.deregisterCommand(createCustomLocator.commandName())
except:
sys.stderr.write( "Failed to deregister node: %s" % nodeTypeName)