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 )