49 import maya.OpenMaya 
as OpenMaya
 
   50 import maya.OpenMayaMPx 
as OpenMayaMPx
 
   51 import maya.OpenMayaRender 
as OpenMayaRender
 
   56 kSimpleEmitterNodeName = 
"spSimpleEmitter" 
   62 TORUS_2PI = 2.0 * TORUS_PI
 
   64 glRenderer = OpenMayaRender.MHardwareRenderer.theRenderer()
 
   65 glFT = glRenderer.glFunctionTable()
 
   67 class simpleEmitter(OpenMayaMPx.MPxEmitterNode):
 
   69         OpenMayaMPx.MPxEmitterNode.__init__(self)
 
   71     def isFullValue( self, plugIndex, block ):
 
   73         mIsFull = OpenMayaMPx.cvar.MPxEmitterNode_mIsFull
 
   76             mhValue = block.inputArrayValue( mIsFull )
 
   77             mhValue.jumpToElement( plugIndex )
 
   78             hValue = mhValue.inputValue( )
 
   79             value = hValue.asBool()
 
   81             sys.stderr.write(
"Error getting the input array value\n")
 
   86     def getWorldPosition( self, point ):
 
   88             thisNode = simpleEmitter.thisMObject( self )
 
   91             worldMatrixAttr = fnThisNode.attribute( 
"worldMatrix" )
 
   94             matrixPlug = matrixPlug.elementByLogicalIndex( 0 )
 
   97             matrixObject = matrixPlug.asMObject(  )
 
  100             worldMatrix = worldMatrixData.matrix( )
 
  102             point.x = worldMatrix( 3, 0 )
 
  103             point.y = worldMatrix( 3, 1 )
 
  104             point.z = worldMatrix( 3, 2 )
 
  106             sys.stderr.write( 
"Error in getWorldPosition\n" )
 
  109     def currentTimeValue( self, block ):
 
  111             mCurrentTime = OpenMayaMPx.cvar.MPxEmitterNode_mCurrentTime
 
  112             hValue = block.inputValue( mCurrentTime )
 
  113             value = hValue.asTime()
 
  115             sys.stderr.write(
"Error getting current time value, returning 0")
 
  119     def startTimeValue( self, plugIndex, block ):
 
  121             mStartTime = OpenMayaMPx.cvar.MPxEmitterNode_mStartTime
 
  122             mhValue = block.inputArrayValue( mStartTime )
 
  123             mhValue.jumpToElement( plugIndex )
 
  124             hValue = mhValue.inputValue( )
 
  125             value = hValue.asTime( )        
 
  127             sys.stderr.write(
"Error getting start time value, setting to 0")
 
  131     def deltaTimeValue( self, plugIndex, block ):
 
  133             mDeltaTime = OpenMayaMPx.cvar.MPxEmitterNode_mDeltaTime
 
  135             mhValue = block.inputArrayValue( mDeltaTime )
 
  136             mhValue.jumpToElement( plugIndex )
 
  138             hValue = mhValue.inputValue()
 
  139             value = hValue.asTime()
 
  141             sys.stderr.write(
"Error getting delta time value, setting to 0\n")
 
  145     def rateValue( self, block ):
 
  147             mRate = OpenMayaMPx.cvar.MPxEmitterNode_mRate
 
  148             hValue = block.inputValue( mRate )
 
  149             value = hValue.asDouble()       
 
  151             sys.stderr.write(
"Error getting rate value, setting to 0\n")
 
  155     def directionValue( self, block ):
 
  157             mDirection = OpenMayaMPx.cvar.MPxEmitterNode_mDirection
 
  158             hValue = block.inputValue( mDirection )
 
  159             value = hValue.asDouble3()
 
  162             sys.stderr.write(
"Error getting direction value, setting to 0,0,0\n")
 
  166     def speedValue( self, block ):
 
  168             mSpeed = OpenMayaMPx.cvar.MPxEmitterNode_mSpeed
 
  169             hValue = block.inputValue( mSpeed )
 
  170             value = hValue.asDouble()       
 
  172             sys.stderr.write(
"Error getting speed value, setting to 0\n")
 
  176     def inheritFactorValue( self, plugIndex, block ):
 
  178             mInheritFactor = OpenMayaMPx.cvar.MPxEmitterNode_mInheritFactor
 
  179             mhValue = block.inputArrayValue( mInheritFactor )
 
  180             mhValue.jumpToElement( plugIndex )
 
  181             hValue = mhValue.inputValue( )
 
  182             value = hValue.asDouble()       
 
  184             sys.stderr.write(
"Error getting inherit factor value, setting to 0\n")
 
  188     def useRotation( self, direction ):
 
  190             thisNode = simpleEmitter.thisMObject(self)
 
  193             worldMatrixAttr = fnThisNode.attribute( 
"worldMatrix" )
 
  196             matrixPlug = matrixPlug.elementByLogicalIndex( 0 )
 
  199             matrixObject = matrixPlug.asMObject( )
 
  202             worldMatrix = worldMatrixData.matrix( )
 
  205             rotatedVector = direction * worldMatrix
 
  207             sys.stderr.write(
"Error getting rotation value, setting to 0,0,0\n")
 
  212     def compute(self, plug, block):
 
  213         mOutput = OpenMayaMPx.cvar.MPxEmitterNode_mOutput
 
  223                 multiIndex = plug.logicalIndex( )
 
  228                 hOutArray = block.outputArrayValue ( mOutput )
 
  232                 bOutArray = hOutArray.builder( )
 
  236                 hOut = bOutArray.addElement( multiIndex )
 
  242                 fnOutput = OpenMaya.MFnArrayAttrsData()
 
  243                 dOutput = fnOutput.create( )
 
  248                 beenFull = simpleEmitter.isFullValue( self, multiIndex, block )
 
  264                 simpleEmitter.getWorldPosition( self, worldPos )
 
  267                 inPosAry.append( worldV )
 
  273                 inVelAry.append( velocity )
 
  279                 cT = simpleEmitter.currentTimeValue( self, block )
 
  280                 sT = simpleEmitter.startTimeValue( self, multiIndex, block )
 
  281                 dT = simpleEmitter.deltaTimeValue( self, multiIndex, block )
 
  285                 if cT <= sT 
or dTValue <= 0.0:
 
  295                     hOut.setMObject( dOutput )
 
  296                     block.setClean( plug )
 
  304                 plugIndex = plug.logicalIndex( )
 
  308                 rate = simpleEmitter.rateValue( self, block )
 
  309                 dtRate = simpleEmitter.deltaTimeValue( self, plugIndex, block )
 
  310                 dtRateDbl = dtRate.asUnits( OpenMaya.MTime.kSeconds )
 
  311                 dblCount = rate * dtRateDbl
 
  312                 intCount = int(dblCount)
 
  313                 emitCountPP.append( intCount )
 
  317                 speed = simpleEmitter.speedValue( self, block )
 
  318                 dirV = simpleEmitter.directionValue( self, block )
 
  319                 inheritFactor = simpleEmitter.inheritFactorValue( self, multiIndex, block )
 
  323                 fnOutPos = fnOutput.vectorArray( 
"position" )
 
  324                 fnOutVel = fnOutput.vectorArray( 
"velocity" )
 
  325                 fnOutTime = fnOutput.doubleArray( 
"timeInStep" )
 
  329                 dt = dT.asUnits( OpenMaya.MTime.kSeconds )
 
  332                 rotatedV = simpleEmitter.useRotation( self, dirV )
 
  336                 simpleEmitter.emit( self, inPosAry, inVelAry, emitCountPP, dt, speed, inheritFactor,\
 
  337                         rotatedV, fnOutPos, fnOutVel, fnOutTime)
 
  342                 hOut.setMObject( dOutput )
 
  343                 block.setClean( plug )
 
  345                 sys.stderr.write(
"simpleEmitter compute error\n")
 
  348             return OpenMaya.kUnknownParameter
 
  350     def emit( self, inPosAry, inVelAry, emitCountPP, dt, speed, inheritFactor, dirV, outPosAry, outVelAry, outTimeAry):
 
  352             posLength = inPosAry.length()
 
  353             velLength = inVelAry.length()
 
  354             countLength = emitCountPP.length()
 
  356             if not posLength == velLength 
or not posLength == countLength:
 
  360             for index 
in range(countLength):
 
  361                 totalCount += emitCountPP[index]
 
  367             for index 
in range(posLength):
 
  368                 emitCount = emitCountPP[index]
 
  372                 sPos = inPosAry[index]
 
  373                 sVel = inVelAry[index]
 
  374                 prePos = sPos - sVel * dt
 
  376                 for i 
in range(emitCount):
 
  377                     alpha = ( float(i) + random.random() ) / float(emitCount)
 
  378                     newPos = prePos * (1.0 - alpha) + sPos * alpha
 
  379                     newVel = dirV * speed
 
  381                     newPos += newVel * ( dt * (1.0 - alpha) )
 
  382                     newVel += sVel * inheritFactor
 
  386                     outPosAry.append( newPos )
 
  387                     outVelAry.append( newVel )
 
  388                     outTimeAry.append( alpha )
 
  390             sys.stderr.write( 
"Error in simpleEmitter.emit\n" )
 
  393     def draw( self, view, path, style, status):
 
  396         for j 
in range(0, SEGMENTS):
 
  398             glFT.glRotatef(float(360.0 * j/SEGMENTS), 0.0, 1.0, 0.0)
 
  399             glFT.glTranslatef( 1.5, 0.0, 0.0)
 
  401             for i 
in range(0, EDGES):
 
  402                 glFT.glBegin(OpenMayaRender.MGL_LINE_STRIP)
 
  404                 p0 = float(TORUS_2PI * i/EDGES)
 
  405                 p1 = float(TORUS_2PI * (i+1)/EDGES)
 
  406                 glFT.glVertex2f(math.cos(p0), math.sin(p0))
 
  407                 glFT.glVertex2f(math.cos(p1), math.sin(p1))
 
  417     return OpenMayaMPx.asMPxPtr( simpleEmitter() )
 
  419 def nodeInitializer():
 
  423 def initializePlugin(mobject):
 
  424     mplugin = OpenMayaMPx.MFnPlugin(mobject)
 
  427         mplugin.registerNode( kSimpleEmitterNodeName, kSimpleEmitterNodeID, \
 
  428                                 nodeCreator, nodeInitializer, OpenMayaMPx.MPxNode.kEmitterNode )
 
  430         sys.stderr.write( 
"Failed to register node: %s\n" % kSimpleEmitterNodeName )
 
  434 def uninitializePlugin(mobject):
 
  435     mplugin = OpenMayaMPx.MFnPlugin(mobject)
 
  438         mplugin.deregisterNode( kSimpleEmitterNodeID )
 
  440         sys.stderr.write( 
"Failed to unregister node: %s\n" % kSimpleEmitterNodeName )