40 import maya.OpenMaya
as OpenMaya
41 import maya.OpenMayaMPx
as OpenMayaMPx
42 import maya.OpenMayaRender
as OpenMayaRender
47 kSimpleEmitterNodeName =
"spSimpleEmitter"
48 kSimpleEmitterNodeID = OpenMaya.MTypeId(0x8700F)
53 TORUS_2PI = 2.0 * TORUS_PI
55 glRenderer = OpenMayaRender.MHardwareRenderer.theRenderer()
56 glFT = glRenderer.glFunctionTable()
58 class simpleEmitter(OpenMayaMPx.MPxEmitterNode):
60 OpenMayaMPx.MPxEmitterNode.__init__(self)
62 def isFullValue( self, plugIndex, block ):
64 mIsFull = OpenMayaMPx.cvar.MPxEmitterNode_mIsFull
67 mhValue = block.inputArrayValue( mIsFull )
68 mhValue.jumpToElement( plugIndex )
69 hValue = mhValue.inputValue( )
70 value = hValue.asBool()
72 sys.stderr.write(
"Error getting the input array value\n")
77 def getWorldPosition( self, point ):
79 thisNode = simpleEmitter.thisMObject( self )
80 fnThisNode = OpenMaya.MFnDependencyNode(thisNode)
82 worldMatrixAttr = fnThisNode.attribute(
"worldMatrix" )
84 matrixPlug = OpenMaya.MPlug( thisNode, worldMatrixAttr )
85 matrixPlug = matrixPlug.elementByLogicalIndex( 0 )
87 matrixObject = OpenMaya.MObject()
88 matrixObject = matrixPlug.asMObject( )
90 worldMatrixData = OpenMaya.MFnMatrixData( matrixObject )
91 worldMatrix = worldMatrixData.matrix( )
93 point.x = worldMatrix( 3, 0 )
94 point.y = worldMatrix( 3, 1 )
95 point.z = worldMatrix( 3, 2 )
97 sys.stderr.write(
"Error in getWorldPosition\n" )
100 def currentTimeValue( self, block ):
102 mCurrentTime = OpenMayaMPx.cvar.MPxEmitterNode_mCurrentTime
103 hValue = block.inputValue( mCurrentTime )
104 value = hValue.asTime()
106 sys.stderr.write(
"Error getting current time value, returning 0")
107 value = OpenMaya.MTime(0.0)
110 def startTimeValue( self, plugIndex, block ):
112 mStartTime = OpenMayaMPx.cvar.MPxEmitterNode_mStartTime
113 mhValue = block.inputArrayValue( mStartTime )
114 mhValue.jumpToElement( plugIndex )
115 hValue = mhValue.inputValue( )
116 value = hValue.asTime( )
118 sys.stderr.write(
"Error getting start time value, setting to 0")
119 value = OpenMaya.MTime(0.0)
122 def deltaTimeValue( self, plugIndex, block ):
124 mDeltaTime = OpenMayaMPx.cvar.MPxEmitterNode_mDeltaTime
126 mhValue = block.inputArrayValue( mDeltaTime )
127 mhValue.jumpToElement( plugIndex )
129 hValue = mhValue.inputValue()
130 value = hValue.asTime()
132 sys.stderr.write(
"Error getting delta time value, setting to 0\n")
133 value = OpenMaya.MTime(0.0)
136 def rateValue( self, block ):
138 mRate = OpenMayaMPx.cvar.MPxEmitterNode_mRate
139 hValue = block.inputValue( mRate )
140 value = hValue.asDouble()
142 sys.stderr.write(
"Error getting rate value, setting to 0\n")
146 def directionValue( self, block ):
148 mDirection = OpenMayaMPx.cvar.MPxEmitterNode_mDirection
149 hValue = block.inputValue( mDirection )
150 value = hValue.asDouble3()
151 dirV = OpenMaya.MVector(value[0], value[1], value[2])
153 sys.stderr.write(
"Error getting direction value, setting to 0,0,0\n")
154 dirV = OpenMaya.MVector(0.0, 0.0, 0.0)
157 def speedValue( self, block ):
159 mSpeed = OpenMayaMPx.cvar.MPxEmitterNode_mSpeed
160 hValue = block.inputValue( mSpeed )
161 value = hValue.asDouble()
163 sys.stderr.write(
"Error getting speed value, setting to 0\n")
167 def inheritFactorValue( self, plugIndex, block ):
169 mInheritFactor = OpenMayaMPx.cvar.MPxEmitterNode_mInheritFactor
170 mhValue = block.inputArrayValue( mInheritFactor )
171 mhValue.jumpToElement( plugIndex )
172 hValue = mhValue.inputValue( )
173 value = hValue.asDouble()
175 sys.stderr.write(
"Error getting inherit factor value, setting to 0\n")
179 def useRotation( self, direction ):
181 thisNode = simpleEmitter.thisMObject(self)
182 fnThisNode = OpenMaya.MFnDependencyNode( thisNode )
184 worldMatrixAttr = fnThisNode.attribute(
"worldMatrix" )
186 matrixPlug = OpenMaya.MPlug( thisNode, worldMatrixAttr )
187 matrixPlug = matrixPlug.elementByLogicalIndex( 0 )
189 matrixObject = OpenMaya.MObject()
190 matrixObject = matrixPlug.asMObject( )
192 worldMatrixData = OpenMaya.MFnMatrixData( matrixObject )
193 worldMatrix = worldMatrixData.matrix( )
195 rotatedVector = OpenMaya.MVector()
196 rotatedVector = direction * worldMatrix
198 sys.stderr.write(
"Error getting rotation value, setting to 0,0,0\n")
199 rotatedVector = OpenMaya.MVector(0.0, 0.0, 0.0)
203 def compute(self, plug, block):
204 mOutput = OpenMayaMPx.cvar.MPxEmitterNode_mOutput
214 multiIndex = plug.logicalIndex( )
219 hOutArray = block.outputArrayValue ( mOutput )
223 bOutArray = hOutArray.builder( )
227 hOut = bOutArray.addElement( multiIndex )
233 fnOutput = OpenMaya.MFnArrayAttrsData()
234 dOutput = fnOutput.create( )
239 beenFull = simpleEmitter.isFullValue( self, multiIndex, block )
251 inPosAry = OpenMaya.MVectorArray()
254 worldPos = OpenMaya.MPoint(0.0, 0.0, 0.0)
255 simpleEmitter.getWorldPosition( self, worldPos )
257 worldV = OpenMaya.MVector(worldPos[0], worldPos[1], worldPos[2])
258 inPosAry.append( worldV )
261 inVelAry = OpenMaya.MVectorArray()
263 velocity = OpenMaya.MVector(0, 0, 0)
264 inVelAry.append( velocity )
270 cT = simpleEmitter.currentTimeValue( self, block )
271 sT = simpleEmitter.startTimeValue( self, multiIndex, block )
272 dT = simpleEmitter.deltaTimeValue( self, multiIndex, block )
276 if cT <= sT
or dTValue <= 0.0:
286 hOut.setMObject( dOutput )
287 block.setClean( plug )
292 emitCountPP = OpenMaya.MIntArray()
295 plugIndex = plug.logicalIndex( )
299 rate = simpleEmitter.rateValue( self, block )
300 dtRate = simpleEmitter.deltaTimeValue( self, plugIndex, block )
301 dtRateDbl = dtRate.asUnits( OpenMaya.MTime.kSeconds )
302 dblCount = rate * dtRateDbl
303 intCount = int(dblCount)
304 emitCountPP.append( intCount )
308 speed = simpleEmitter.speedValue( self, block )
309 dirV = simpleEmitter.directionValue( self, block )
310 inheritFactor = simpleEmitter.inheritFactorValue( self, multiIndex, block )
314 fnOutPos = fnOutput.vectorArray(
"position" )
315 fnOutVel = fnOutput.vectorArray(
"velocity" )
316 fnOutTime = fnOutput.doubleArray(
"timeInStep" )
320 dt = dT.asUnits( OpenMaya.MTime.kSeconds )
323 rotatedV = simpleEmitter.useRotation( self, dirV )
327 simpleEmitter.emit( self, inPosAry, inVelAry, emitCountPP, dt, speed, inheritFactor,\
328 rotatedV, fnOutPos, fnOutVel, fnOutTime)
333 hOut.setMObject( dOutput )
334 block.setClean( plug )
336 sys.stderr.write(
"simpleEmitter compute error\n")
339 return OpenMaya.kUnknownParameter
341 def emit( self, inPosAry, inVelAry, emitCountPP, dt, speed, inheritFactor, dirV, outPosAry, outVelAry, outTimeAry):
343 posLength = inPosAry.length()
344 velLength = inVelAry.length()
345 countLength = emitCountPP.length()
347 if not posLength == velLength
or not posLength == countLength:
351 for index
in range(countLength):
352 totalCount += emitCountPP[index]
358 for index
in range(posLength):
359 emitCount = emitCountPP[index]
363 sPos = inPosAry[index]
364 sVel = inVelAry[index]
365 prePos = sPos - sVel * dt
367 for i
in range(emitCount):
368 alpha = ( float(i) + random.random() ) / float(emitCount)
369 newPos = prePos * (1.0 - alpha) + sPos * alpha
370 newVel = dirV * speed
372 newPos += newVel * ( dt * (1.0 - alpha) )
373 newVel += sVel * inheritFactor
377 outPosAry.append( newPos )
378 outVelAry.append( newVel )
379 outTimeAry.append( alpha )
381 sys.stderr.write(
"Error in simpleEmitter.emit\n" )
384 def draw( self, view, path, style, status):
387 for j
in range(0, SEGMENTS):
389 glFT.glRotatef(float(360.0 * j/SEGMENTS), 0.0, 1.0, 0.0)
390 glFT.glTranslatef( 1.5, 0.0, 0.0)
392 for i
in range(0, EDGES):
393 glFT.glBegin(OpenMayaRender.MGL_LINE_STRIP)
395 p0 = float(TORUS_2PI * i/EDGES)
396 p1 = float(TORUS_2PI * (i+1)/EDGES)
397 glFT.glVertex2f(math.cos(p0), math.sin(p0))
398 glFT.glVertex2f(math.cos(p1), math.sin(p1))
408 return OpenMayaMPx.asMPxPtr( simpleEmitter() )
410 def nodeInitializer():
414 def initializePlugin(mobject):
415 mplugin = OpenMayaMPx.MFnPlugin(mobject)
418 mplugin.registerNode( kSimpleEmitterNodeName, kSimpleEmitterNodeID, \
419 nodeCreator, nodeInitializer, OpenMayaMPx.MPxNode.kEmitterNode )
421 sys.stderr.write(
"Failed to register node: %s\n" % kSimpleEmitterNodeName )
425 def uninitializePlugin(mobject):
426 mplugin = OpenMayaMPx.MFnPlugin(mobject)
429 mplugin.deregisterNode( kSimpleEmitterNodeID )
431 sys.stderr.write(
"Failed to unregister node: %s\n" % kSimpleEmitterNodeName )