2 //**************************************************************************/
3 // Copyright (c) 2016 Autodesk, Inc.
4 // All rights reserved.
6 // These coded instructions, statements, and computer programs contain
7 // unpublished proprietary information written by Autodesk, Inc., and are
8 // protected by Federal copyright law. They may not be disclosed to third
9 // parties or copied or duplicated in any form, in whole or in part, without
10 // the prior written consent of Autodesk, Inc.
13 import maya.api.OpenMaya
as om
14 import maya.api.OpenMayaRender
as omr
15 import maya.cmds
as cmds
21 class RenderOverrideOptions(om.MPxNode):
22 kTypeId = om.MTypeId(0x00080043)
23 kTypeName =
"RenderOverrideOptions"
27 reflectionTint = om.MObject()
28 enableReflections = om.MObject()
29 blurReflections = om.MObject()
30 reflectionRange = om.MObject()
31 saturation = om.MObject()
38 return RenderOverrideOptions()
43 stringData = om.MFnStringData().create(
'')
44 attrFn = om.MFnTypedAttribute()
45 numAttrFn = om.MFnNumericAttribute()
46 numericData = om.MFnNumericData()
49 RenderOverrideOptions.enableReflections = numAttrFn.create(
"enableReflections",
"ef", om.MFnNumericData.kBoolean)
50 numAttrFn.default =
True
51 numAttrFn.storable =
True
52 numAttrFn.keyable =
True
53 numAttrFn.readable =
True
54 numAttrFn.writable =
True
55 numAttrFn.hidden =
False
56 om.MPxNode.addAttribute(RenderOverrideOptions.enableReflections)
59 RenderOverrideOptions.reflectionTint = numAttrFn.createColor(
"reflectionTint",
"rt")
60 numAttrFn.default = (0.3, 0.3, 0.3)
61 numAttrFn.storable =
True
62 numAttrFn.keyable =
True
63 numAttrFn.readable =
True
64 numAttrFn.writable =
True
65 numAttrFn.hidden =
False
66 om.MPxNode.addAttribute(RenderOverrideOptions.reflectionTint)
68 RenderOverrideOptions.saturation = numAttrFn.create(
"saturation",
"sat", om.MFnNumericData.kFloat)
69 numAttrFn.default = 1.0
70 numAttrFn.storable =
True
71 numAttrFn.keyable =
True
72 numAttrFn.readable =
True
73 numAttrFn.writable =
True
74 numAttrFn.hidden =
False
75 om.MPxNode.addAttribute(RenderOverrideOptions.saturation)
77 RenderOverrideOptions.blurReflections = numAttrFn.create(
"blurReflections",
"br", om.MFnNumericData.kBoolean)
78 numAttrFn.default =
True
79 numAttrFn.storable =
True
80 numAttrFn.keyable =
True
81 numAttrFn.readable =
True
82 numAttrFn.writable =
True
83 numAttrFn.hidden =
False
84 om.MPxNode.addAttribute(RenderOverrideOptions.blurReflections)
86 RenderOverrideOptions.reflectionRange = numAttrFn.create(
"reflectionRange",
"rr", om.MFnNumericData.k2Float)
87 numAttrFn.default = (0.0, 100.0)
88 numAttrFn.storable =
True
89 numAttrFn.keyable =
True
90 numAttrFn.readable =
True
91 numAttrFn.writable =
True
92 numAttrFn.hidden =
False
93 om.MPxNode.addAttribute(RenderOverrideOptions.reflectionRange)
96 super(RenderOverrideOptions, self).__init__()
98 def postConstructor(self):
101 om.MNodeMessage.addAttributeChangedCallback(self.thisMObject(), RenderOverrideOptions.attrChangedCB, self)
104 def attrChangedCB(msg, plg, otherPlug, self):
107 def _selectPlug(name):
108 sl = om.MSelectionList()
116 if plg.isElement
and name.find(
'[') == -1:
122 def nameToNode(name):
123 """Returns the MObject matching given name or None if not found.
124 Raises RuntimeError if name is ambiguous."""
125 plg = _selectPlug(name +
".message")
126 return plg.node()
if plg
else None
128 def getFloat4PlugValue(plug):
129 object = plug.asMObject()
130 numDataFn = om.MFnNumericData( object )
131 return numDataFn.getData( )
133 def getFloat3PlugValue(plug):
134 object = plug.asMObject()
135 numDataFn = om.MFnNumericData( object )
136 return numDataFn.getData( )
138 def getFloat2PlugValue(plug):
139 object = plug.asMObject()
140 numDataFn = om.MFnNumericData( object )
141 return numDataFn.getData( )
143 def getBoolPlugValue(plug):
146 def getFloatPlugValue(plug):
147 return plug.asFloat()
149 def getIntPlugValue(plug):
152 class FragmentSceneRender(omr.MSceneRender):
153 def __init__(self, name):
154 super(FragmentSceneRender, self).__init__(name,
"GroundReflections")
156 def preSceneRender(self, context):
157 params = self.getParameters()
162 optionsNodeName =
'groundReflectionOptions'
163 optionObj = nameToNode(optionsNodeName)
164 if optionObj
is None:
165 optionObj = nameToNode(cmds.createNode(RenderOverrideOptions.kTypeName, name=optionsNodeName, skipSelect=
True))
167 if optionObj
is not None:
169 optionPlug = om.MPlug(optionObj, RenderOverrideOptions.enableReflections)
170 if optionPlug
is not None:
171 enabled = getBoolPlugValue(optionPlug)
172 params.setParameter(
'EnableReflection', enabled)
175 optionPlug = om.MPlug(optionObj, RenderOverrideOptions.blurReflections)
176 if optionPlug
is not None:
177 blur = getBoolPlugValue(optionPlug)
179 params.setParameter(
'BlurType', 3)
181 params.setParameter(
'BlurType', 0)
184 optionPlug = om.MPlug(optionObj, RenderOverrideOptions.reflectionTint)
185 if optionPlug
is not None:
186 color = getFloat3PlugValue(optionPlug)
187 params.setParameter(
'Color', color)
190 optionPlug = om.MPlug(optionObj, RenderOverrideOptions.saturation)
191 if optionPlug
is not None:
192 val = getFloatPlugValue(optionPlug)
193 params.setParameter(
'Saturation', val)
196 optionPlug = om.MPlug(optionObj, RenderOverrideOptions.reflectionRange)
197 if optionPlug
is not None:
198 val = getFloat2PlugValue(optionPlug)
199 params.setParameter(
'DistanceRange', val)
201 class FragmentRenderOverride(omr.MRenderOverride):
203 def __init__(self, name):
204 self.operatioIndex = 0
205 self.operations = [FragmentSceneRender(
"sceneAndGroundReflections"),
207 omr.MPresentTarget(
"present")]
210 self.operations[0].clearOperation().setOverridesColors(
False)
212 super(FragmentRenderOverride, self).__init__(name)
215 return 'Ground Reflections'
217 def setup(self, destination):
218 super(FragmentRenderOverride, self).setup(destination)
221 super(FragmentRenderOverride, self).cleanup()
223 def supportedDrawAPIs(self):
224 return omr.MRenderer.kAllDevices
226 def startOperationIterator(self):
227 self.operationIndex = 0
230 def renderOperation(self):
231 return self.operations[self.operationIndex]
233 def nextRenderOperation(self):
234 self.operationIndex += 1
235 return self.operationIndex < len(self.operations)
238 fragmentRenderer =
None
240 def initializePlugin(mobject):
244 omr.MRenderer.getShaderManager().addShaderPath(pathToPlugin +
"Shaders/OGSFX")
245 omr.MRenderer.getShaderManager().addShaderPath(pathToPlugin +
"Shaders/HLSL")
246 omr.MRenderer.getShaderManager().addShaderPath(pathToPlugin +
"Shaders/Cg")
248 omr.MRenderer.getFragmentManager().addFragmentPath(pathToPlugin +
"ScriptFragment")
249 omr.MRenderer.getFragmentManager().addFragmentGraphFromFile(
"GroundReflections.xml")
251 plugin = om.MFnPlugin(mobject,
"Autodesk",
"3.0",
"Any")
252 plugin.registerNode(RenderOverrideOptions.kTypeName, RenderOverrideOptions.kTypeId, RenderOverrideOptions.creator, RenderOverrideOptions.initializer)
254 global fragmentRenderer
255 fragmentRenderer = FragmentRenderOverride(
'GroundReflectionsOverride')
256 omr.MRenderer.registerOverride(fragmentRenderer)
258 def uninitializePlugin(mobject):
259 global fragmentRenderer
260 plugin = om.MFnPlugin(mobject)
262 plugin.deregisterNode(apiMeshCreator.id)
263 omr.MRenderer.unregisterOverride(fragmentRenderer)
264 fragmentRenderer =
None
266 sys.stderr.write(
"Failed to deregister node\n")