1 from __future__
import division
50 from builtins
import range
51 import maya.OpenMaya
as OpenMaya
52 import maya.OpenMayaMPx
as OpenMayaMPx
53 import maya.OpenMayaRender
as OpenMayaRender
58 kSimpleEmitterNodeName =
"py1SimpleEmitter"
64 TORUS_2PI = 2.0 * TORUS_PI
66 glRenderer = OpenMayaRender.MHardwareRenderer.theRenderer()
67 glFT = glRenderer.glFunctionTable()
69 class simpleEmitter(OpenMayaMPx.MPxEmitterNode):
71 OpenMayaMPx.MPxEmitterNode.__init__(self)
73 def isFullValue( self, plugIndex, block ):
75 mIsFull = OpenMayaMPx.cvar.MPxEmitterNode_mIsFull
78 mhValue = block.inputArrayValue( mIsFull )
79 mhValue.jumpToElement( plugIndex )
80 hValue = mhValue.inputValue( )
81 value = hValue.asBool()
83 sys.stderr.write(
"Error getting the input array value\n")
88 def getWorldPosition( self, point ):
90 thisNode = simpleEmitter.thisMObject( self )
93 worldMatrixAttr = fnThisNode.attribute(
"worldMatrix" )
96 matrixPlug = matrixPlug.elementByLogicalIndex( 0 )
99 matrixObject = matrixPlug.asMObject( )
102 worldMatrix = worldMatrixData.matrix( )
104 point.x = worldMatrix( 3, 0 )
105 point.y = worldMatrix( 3, 1 )
106 point.z = worldMatrix( 3, 2 )
108 sys.stderr.write(
"Error in getWorldPosition\n" )
111 def currentTimeValue( self, block ):
113 mCurrentTime = OpenMayaMPx.cvar.MPxEmitterNode_mCurrentTime
114 hValue = block.inputValue( mCurrentTime )
115 value = hValue.asTime()
117 sys.stderr.write(
"Error getting current time value, returning 0")
121 def startTimeValue( self, plugIndex, block ):
123 mStartTime = OpenMayaMPx.cvar.MPxEmitterNode_mStartTime
124 mhValue = block.inputArrayValue( mStartTime )
125 mhValue.jumpToElement( plugIndex )
126 hValue = mhValue.inputValue( )
127 value = hValue.asTime( )
129 sys.stderr.write(
"Error getting start time value, setting to 0")
133 def deltaTimeValue( self, plugIndex, block ):
135 mDeltaTime = OpenMayaMPx.cvar.MPxEmitterNode_mDeltaTime
137 mhValue = block.inputArrayValue( mDeltaTime )
138 mhValue.jumpToElement( plugIndex )
140 hValue = mhValue.inputValue()
141 value = hValue.asTime()
143 sys.stderr.write(
"Error getting delta time value, setting to 0\n")
147 def rateValue( self, block ):
149 mRate = OpenMayaMPx.cvar.MPxEmitterNode_mRate
150 hValue = block.inputValue( mRate )
151 value = hValue.asDouble()
153 sys.stderr.write(
"Error getting rate value, setting to 0\n")
157 def directionValue( self, block ):
159 mDirection = OpenMayaMPx.cvar.MPxEmitterNode_mDirection
160 hValue = block.inputValue( mDirection )
161 value = hValue.asDouble3()
164 sys.stderr.write(
"Error getting direction value, setting to 0,0,0\n")
168 def speedValue( self, block ):
170 mSpeed = OpenMayaMPx.cvar.MPxEmitterNode_mSpeed
171 hValue = block.inputValue( mSpeed )
172 value = hValue.asDouble()
174 sys.stderr.write(
"Error getting speed value, setting to 0\n")
178 def inheritFactorValue( self, plugIndex, block ):
180 mInheritFactor = OpenMayaMPx.cvar.MPxEmitterNode_mInheritFactor
181 mhValue = block.inputArrayValue( mInheritFactor )
182 mhValue.jumpToElement( plugIndex )
183 hValue = mhValue.inputValue( )
184 value = hValue.asDouble()
186 sys.stderr.write(
"Error getting inherit factor value, setting to 0\n")
190 def useRotation( self, direction ):
192 thisNode = simpleEmitter.thisMObject(self)
195 worldMatrixAttr = fnThisNode.attribute(
"worldMatrix" )
198 matrixPlug = matrixPlug.elementByLogicalIndex( 0 )
201 matrixObject = matrixPlug.asMObject( )
204 worldMatrix = worldMatrixData.matrix( )
207 rotatedVector = direction * worldMatrix
209 sys.stderr.write(
"Error getting rotation value, setting to 0,0,0\n")
214 def compute(self, plug, block):
215 mOutput = OpenMayaMPx.cvar.MPxEmitterNode_mOutput
225 multiIndex = plug.logicalIndex( )
230 hOutArray = block.outputArrayValue ( mOutput )
234 bOutArray = hOutArray.builder( )
238 hOut = bOutArray.addElement( multiIndex )
244 fnOutput = OpenMaya.MFnArrayAttrsData()
245 dOutput = fnOutput.create( )
250 beenFull = simpleEmitter.isFullValue( self, multiIndex, block )
266 simpleEmitter.getWorldPosition( self, worldPos )
269 inPosAry.append( worldV )
275 inVelAry.append( velocity )
281 cT = simpleEmitter.currentTimeValue( self, block )
282 sT = simpleEmitter.startTimeValue( self, multiIndex, block )
283 dT = simpleEmitter.deltaTimeValue( self, multiIndex, block )
287 if cT <= sT
or dTValue <= 0.0:
297 hOut.setMObject( dOutput )
298 block.setClean( plug )
306 plugIndex = plug.logicalIndex( )
310 rate = simpleEmitter.rateValue( self, block )
311 dtRate = simpleEmitter.deltaTimeValue( self, plugIndex, block )
312 dtRateDbl = dtRate.asUnits( OpenMaya.MTime.kSeconds )
313 dblCount = rate * dtRateDbl
314 intCount = int(dblCount)
315 emitCountPP.append( intCount )
319 speed = simpleEmitter.speedValue( self, block )
320 dirV = simpleEmitter.directionValue( self, block )
321 inheritFactor = simpleEmitter.inheritFactorValue( self, multiIndex, block )
325 fnOutPos = fnOutput.vectorArray(
"position" )
326 fnOutVel = fnOutput.vectorArray(
"velocity" )
327 fnOutTime = fnOutput.doubleArray(
"timeInStep" )
331 dt = dT.asUnits( OpenMaya.MTime.kSeconds )
334 rotatedV = simpleEmitter.useRotation( self, dirV )
338 simpleEmitter.emit( self, inPosAry, inVelAry, emitCountPP, dt, speed, inheritFactor,\
339 rotatedV, fnOutPos, fnOutVel, fnOutTime)
344 hOut.setMObject( dOutput )
345 block.setClean( plug )
347 sys.stderr.write(
"simpleEmitter compute error\n")
350 return OpenMaya.kUnknownParameter
352 def emit( self, inPosAry, inVelAry, emitCountPP, dt, speed, inheritFactor, dirV, outPosAry, outVelAry, outTimeAry):
354 posLength = inPosAry.length()
355 velLength = inVelAry.length()
356 countLength = emitCountPP.length()
358 if not posLength == velLength
or not posLength == countLength:
362 for index
in range(countLength):
363 totalCount += emitCountPP[index]
369 for index
in range(posLength):
370 emitCount = emitCountPP[index]
374 sPos = inPosAry[index]
375 sVel = inVelAry[index]
376 prePos = sPos - sVel * dt
378 for i
in range(emitCount):
379 alpha = ( float(i) + random.random() ) / float(emitCount)
380 newPos = prePos * (1.0 - alpha) + sPos * alpha
381 newVel = dirV * speed
383 newPos += newVel * ( dt * (1.0 - alpha) )
384 newVel += sVel * inheritFactor
388 outPosAry.append( newPos )
389 outVelAry.append( newVel )
390 outTimeAry.append( alpha )
391 except Exception
as e:
392 sys.stderr.write(
"Error in simpleEmitter.emit\n" )
395 def draw( self, view, path, style, status):
398 for j
in range(0, SEGMENTS):
400 glFT.glRotatef(float(360.0 * j/SEGMENTS), 0.0, 1.0, 0.0)
401 glFT.glTranslatef( 1.5, 0.0, 0.0)
403 for i
in range(0, EDGES):
404 glFT.glBegin(OpenMayaRender.MGL_LINE_STRIP)
406 p0 = float(TORUS_2PI * i/EDGES)
407 p1 = float(TORUS_2PI * (i+1)/EDGES)
408 glFT.glVertex2f(math.cos(p0), math.sin(p0))
409 glFT.glVertex2f(math.cos(p1), math.sin(p1))
419 return OpenMayaMPx.asMPxPtr( simpleEmitter() )
421 def nodeInitializer():
425 def initializePlugin(mobject):
426 mplugin = OpenMayaMPx.MFnPlugin(mobject)
429 mplugin.registerNode( kSimpleEmitterNodeName, kSimpleEmitterNodeID, \
430 nodeCreator, nodeInitializer, OpenMayaMPx.MPxNode.kEmitterNode )
432 sys.stderr.write(
"Failed to register node: %s\n" % kSimpleEmitterNodeName )
436 def uninitializePlugin(mobject):
437 mplugin = OpenMayaMPx.MFnPlugin(mobject)
440 mplugin.deregisterNode( kSimpleEmitterNodeID )
442 sys.stderr.write(
"Failed to unregister node: %s\n" % kSimpleEmitterNodeName )