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)

Reply via email to