MPxSubSceneOverride Class Reference

MPxSubSceneOverride Class Referenceabstract

#include <MPxSubSceneOverride.h>

Class Description

Base class for Viewport 2.0 drawing of DAG nodes which represent sub-scenes.

MPxSubSceneOverride allows the user to completely define the renderable units (render items) needed to draw a specific DAG object type in Maya when using Viewport 2.0.

This class is independent of any specific hardware draw API. Implementations operate using the MRenderItem interface and provide a list of the render items needed to draw all instances of the associated DAG object. One implementation of the override will be created for each object in the Maya scene whose classification string satisfies the classification string used when registering the override. If the associated DAG object is instanced, the override is responsible for drawing all instances.

The collection of render items is stored in an MSubSceneContainer object. This container is suitable for storing and accessing large numbers of render items (thousands or tens of thousands) in a high performance manner. Implementations are responsible for assigning a shader and an optional matrix to each render item and must also provide the geometry for each render item as required by its shader. Geometry may be shared between render items and management of the geometry is up to the implementation.

MPxSubSceneOverride falls in between MPxDrawOverride and MPxGeometryOverride with respect to the amount of control given to the implementation. MPxDrawOverride allows full control over the entire draw of the object, but as a result the implementation is entirely responsible for the draw. MPxGeometryOverride is relatively simple to work with but as a result only limited control of the draw is available. MPxSubSceneOverride is allowed to fully define all render items, geometry and shaders providing a high degree of control. However this definition is abstracted from the hardware draw API so only one implementation is needed to get support for both DirectX and OpenGL. Furthermore, Maya will handle actually drawing the render items and thus the items can participate fully in the Maya rendering pipeline (including screen-space effects like SSAO, transparency sorting, shadow casting/receiving, etc.). Finally, render items may specify which draw modes they should draw in (wireframe, shaded, textured, bounding box) so there is no need for the implementation to track these modes manually.

MPxSubSceneOverride can be used to provide Viewport 2.0 support for any type of DAG object, however it is optimized for use in cases where a single DAG object needs to produce a large number of renderables which are not necessarily located at the same point in space. For example, this interface would be a good choice for implementing support for a custom node that needs to read and draw a full scene based on a description from a cache file.

MPxSubSceneOverride has three stages. In each stage, an instance of MFrameContext is provided to give some information about the current state of the renderer. The implementation is also free to query any information it needs from Maya.

1) requiresUpdate() : In this call, the implementation is given constant access to the set of render items for the object. On the first call it will be empty. If the method returns true, Maya will call update() and the implementation will be given the opportunity to add/remove render items from the set as well as to modify those items. Render item state is maintained as long as the render item is stored in the MSubSceneContainer object. Thus, if nothing needs to be changed this method may return false to skip the update phase.

2) update() : In this call, the implementation may add/remove render items to/from the set, and it may modify existing render items. For each render item the implementation is required to call setGeometryForRenderItem() to provide the geometry for the render item. Render items without geometry will not draw.

3) addUIDrawables() : In this call, the implementation may use MUIDrawManager to draw simple UI shapes like lines, circles, text, etc. If areUIDrawablesDirty() method returns true, the UI drawables would be cleared and re-added every refresh. If the dirty is false, the UI drawables are being persistently kept until either the DAG object associated with the override is destroyed or the override is deregistered. Note that the UI drawables don't support instancing draw.

If at the end of these three stages further update is required then furtherUpdateRequired() can be overridden to indicate whether the three stages need to be called again.

Implementations of MPxSubSceneOverride must be registered with Maya through MDrawRegistry.

+ Examples:

Public Member Functions

 MPxSubSceneOverride (const MObject &obj)
 Construct an MPxSubSceneOverride. More...
 
virtual ~MPxSubSceneOverride ()
 Destructor.
 
virtual MHWRender::DrawAPI supportedDrawAPIs () const
 Returns the draw API supported by this override. More...
 
virtual bool requiresUpdate (const MSubSceneContainer &container, const MFrameContext &frameContext) const =0
 On each frame Maya will give each instantiated MPxSubSceneOverride object a chance to update its set of render items. More...
 
virtual void update (MSubSceneContainer &container, const MFrameContext &frameContext)=0
 This method is called by Maya on each frame as long as the implementation of MPxSubSceneOverride::requiresUpdate() returns true. More...
 
virtual bool furtherUpdateRequired (const MFrameContext &frameContext)
 This method is called by Maya following update() to allow the override to indicate whether further processing is required. More...
 
virtual bool areUIDrawablesDirty () const
 Determines whether addUIDrawables() should be called on the next refresh. More...
 
virtual bool hasUIDrawables () const
 Tells Maya whether addUIDrawables() should be called. More...
 
virtual void addUIDrawables (MUIDrawManager &drawManager, const MFrameContext &frameContext)
 Provides access to a MUIDrawManager, which can be used to queue up operations to draw simple UI shapes like lines, circles, text, etc. More...
 
virtual bool getSelectionPath (const MRenderItem &renderItem, MDagPath &dagPath) const
 This method is called by Maya following selection to allow specifying the selection path for a single render item. More...
 
virtual bool getInstancedSelectionPath (const MRenderItem &renderItem, const MIntersection &intersection, MDagPath &dagPath) const
 This method is called by Maya following selection to allow specifying the selection path for a single instantiable render item. More...
 
virtual void updateSelectionGranularity (const MDagPath &path, MSelectionContext &selectionContext)
 Maya calls this function during the pre-filtering phase of the viewport 2.0 selection and is used to allow derived classes to modify the selection context of the given DAG object. More...
 
MStatus setGeometryForRenderItem (MRenderItem &renderItem, const MVertexBufferArray &vertexBuffers, const MIndexBuffer &indexBuffer, const MBoundingBox *objectBox)
 Call this method to provide the geometry for a render item. More...
 
unsigned int addInstanceTransform (MRenderItem &renderItem, const MMatrix &transform)
 Add an additional instance for a render item. More...
 
MStatus setInstanceTransformArray (MRenderItem &renderItem, const MMatrixArray &matrixArray)
 Sets the entire instance array for a render item. More...
 
MStatus updateInstanceTransform (MRenderItem &renderItem, unsigned int instanceId, const MMatrix &transform)
 Update the instance transform matrix for one instance of a render item. More...
 
MStatus removeInstance (MRenderItem &renderItem, unsigned int instanceId)
 Remove one instance of a render item. More...
 
MStatus removeAllInstances (MRenderItem &renderItem)
 Remove all instances for a render item. More...
 
MStatus setExtraInstanceData (MRenderItem &renderItem, const MString &parameterName, const MFloatArray &data)
 Adds an extra stream of instanced data to an instanced render item. More...
 
MStatus setExtraInstanceData (MRenderItem &renderItem, unsigned int instanceId, const MString &parameterName, const MFloatArray &data)
 Set the value for the specified extra instance data stream for a particular instance of the instanced render item. More...
 
MStatus removeExtraInstanceData (MRenderItem &renderItem, const MString &parameterName)
 Remove an entire extra instance data stream from the instanced render item. More...
 
MStatus setAllowTransparentInstances (MRenderItem &renderItem, bool allow)
 Instancing is disabled automatically by default when the shader is transparent. More...
 

Static Public Member Functions

static bool pointSnappingActive ()
 Returns true if selection has been launched to find snap points. More...
 
static const char * className ()
 Returns the name of this class. More...
 

Constructor & Destructor Documentation

MPxSubSceneOverride ( const MObject obj)

Construct an MPxSubSceneOverride.

Parameters
[in]objThe Maya object this override draws

Member Function Documentation

MHWRender::DrawAPI supportedDrawAPIs ( ) const
virtual

Returns the draw API supported by this override.

The returned value may be formed as the bitwise or of MHWRender::DrawAPI elements to indicate that the override supports multiple draw APIs. This method returns MHWRender::kOpenGL by default.

Returns
The draw API supported by this override
+ Examples:
bool requiresUpdate ( const MSubSceneContainer container,
const MFrameContext frameContext 
) const
pure virtual

On each frame Maya will give each instantiated MPxSubSceneOverride object a chance to update its set of render items.

Before beginning the update process for a specific override, Maya will first call this method to give the override a chance to indicate whether or not an update is necessary. If this method returns false, MPxSubSceneOverride::update() will not be called.

The set of render items for this override must not be modified in this method.

Parameters
[in]containerThe container for this override
[in]frameContextContext information for the current frame
Returns
True if Maya should trigger the update process for this override
+ Examples:
void update ( MSubSceneContainer container,
const MFrameContext frameContext 
)
pure virtual

This method is called by Maya on each frame as long as the implementation of MPxSubSceneOverride::requiresUpdate() returns true.

In this method, the MSubSceneContainer should be populated with the render items that are required to draw the associated DAG object. The render items will remain in the container until they are explicitly removed or the associated object is deleted. Render items in the container may also be modified at this time.

All render items in the container upon completion of this method will be processed for drawing. Any such items which pass all filtering tests for the active viewport will draw. At a minimum, render items must be enabled, have a valid shader and valid geometry in order to draw in Viewport 2.0.

It is the responsibility of this method to call MHWRender::MRenderer::setLightsAndShadowsDirty() to trigger recomputation of any shadow maps in the scene (if required).

Parameters
[in]containerThe container for this override
[in]frameContextContext information for the current frame
+ Examples:
bool furtherUpdateRequired ( const MFrameContext frameContext)
virtual

This method is called by Maya following update() to allow the override to indicate whether further processing is required.

If so, then requiresUpdate() and update() will be called again at a later time. In general this will occur when no active processing is occuring (when "idle").

It is the responsibility of the plug-in to ensure that this method does not continuously request further updates as it may block the execution of other idle time events.

Parameters
[in]frameContextContext information for the current frame
Returns
True if further update is required. The default value return is false.
+ Examples:
bool areUIDrawablesDirty ( ) const
virtual

Determines whether addUIDrawables() should be called on the next refresh.

If you've overridden addUIDrawables() then at the start of each refresh Maya will destroy the drawables added in the previous refresh and call addUIDrawables() again. If you override this method to return false then Maya will preserve the UI drawables from the previous refresh until either the DAG object associated with the override is destroyed, or the override is deregistered.

Returns
True if addUIDrawables() should be called on the next refresh, false if not. The default is true.
+ Examples:
bool hasUIDrawables ( ) const
virtual

Tells Maya whether addUIDrawables() should be called.

If you've overridden addUIDrawables() then you must also override this method to return true.

Returns
True if Maya should call addUIDrawables().
+ Examples:
void addUIDrawables ( MUIDrawManager drawManager,
const MFrameContext frameContext 
)
virtual

Provides access to a MUIDrawManager, which can be used to queue up operations to draw simple UI shapes like lines, circles, text, etc.

If you override this method you must also override hasUIDrawables() to return true, otherwise this method will not be called.

If you are not going to override this function, please don't make 'hasUIDrawables()' return true or there may be some wasted performance overhead.

By default the drawables will persist until either the DAG object associated with the override is destroyed or the override is deregistered. If you don't want them to be redrawn on each refresh, override areUIDrawablesDirty() to return false. That will cause the drawables to be destroyed on next refresh and this method called again to replace them.

Parameters
[in]drawManagerThe UI draw manager, it can be used to draw some simple geometry including text
[in]frameContextFrame level context information
+ Examples:
bool getSelectionPath ( const MRenderItem renderItem,
MDagPath dagPath 
) const
virtual

This method is called by Maya following selection to allow specifying the selection path for a single render item.

It will be called once for each MRenderItem submitted in MPxSubSceneOverride::update() that intersects the selection frustum. If none of the MRenderItem intersects, then this callback will remain silent.

When selection filtering is active, or in case of single click selection it is possible that the item will not be in the final selection list.

The default implementation will return the first path to the associated DAG object. Specialization is required to provide support for multiple instances of the DAG object.

Note: If your SubScene override plugin supports instancing, then you should overload getInstancedSelectionPath() instead to get all the necessary information to be able to return a proper path.

Parameters
[in]renderItemRender item found inside the selection frustum
[out]dagPaththe MDagPath associated with the provided render item.
Returns
True if a dag path was found for the render item.
+ Examples:
bool getInstancedSelectionPath ( const MRenderItem renderItem,
const MIntersection intersection,
MDagPath dagPath 
) const
virtual

This method is called by Maya following selection to allow specifying the selection path for a single instantiable render item.

It is identical to getSelectionPath() but includes MIntersection information to properly distinguish between instances when the viewport is in GPU acceleration mode.

In GPU acceleration mode, the renderItem will be the one of the master instance and the value of intersection.instanceID() will match the value returned by addInstanceTransform(). In regular non GPU accelerated mode, the renderItem will be the one directly associated with the instance. If intersection.instanceID() is equal to -1, then the geometry was not GPU accelerated.

Parameters
[in]renderItemRender item found inside the selection frustum, or master item in GPU accelerated mode.
[in]intersectionExtra information to help find out how the render item got selected.
[out]dagPaththe MDagPath associated with the provided render item.
Returns
True if a dag path was found for the instanciable render item.
+ Examples:
void updateSelectionGranularity ( const MDagPath path,
MSelectionContext selectionContext 
)
virtual

Maya calls this function during the pre-filtering phase of the viewport 2.0 selection and is used to allow derived classes to modify the selection context of the given DAG object.

This is useful to specify the selection level, which defines what can be selected on the object :

Implementation of this method here is empty, and default selection level is set to kObject.

Parameters
[in]pathThe path to the instance to update the selection context for
[out]selectionContextThe selection context
+ Examples:
bool pointSnappingActive ( )
static

Returns true if selection has been launched to find snap points.

To participate, you need to have at least one render item with point geometry and MSelectionMask::kSelectPointsForGravity set in MRenderItem::selectableMask().

Returns
  • true Snapping is active
  • false Not currently snapping
MStatus setGeometryForRenderItem ( MRenderItem renderItem,
const MVertexBufferArray vertexBuffers,
const MIndexBuffer indexBuffer,
const MBoundingBox objectBox 
)

Call this method to provide the geometry for a render item.

Although the render item will add a reference to each buffer, ultimate ownership of the geometric data remains with the caller. This method may only be called on render items which have been generated by this override and it may only be called during update(). Buffers may be shared among multiple render items. This method will replace any geometry currently associated with the render item with the newly provided geometry.

The bounding box parameter to this method is optional. If NULL, Maya will attempt to calculate the box automatically. Note that this may require a read-back of vertex data from the graphics card which can be a very slow operation. It is better to supply a correct bounding box whenever possible.

It is the responsibility of the caller to ensure that the buffers provided fulfill the geometry requirements of the shader for the render item. If the requirements are not met, the render item will not draw. If there is no shader assigned to the render item, this method will fail.

When a geometry is completely defined by its vertex buffers, like when drawing all points in a MGeometry::kPoints render item, it is possible to provide an empty MIndexBuffer. The geometry will then be drawn using a non-indexed draw call like glDrawArrays() or ID3D11DeviceContext::Draw().

Parameters
[in]renderItemThe render item to provide geometry for
[in]vertexBuffersThe vertex buffers for the geometry
[in]indexBufferThe index buffer for the geometry
[in]objectBoxObject-space bounding box, may be NULL
Returns
Status code
Status Codes:
unsigned int addInstanceTransform ( MRenderItem renderItem,
const MMatrix transform 
)

Add an additional instance for a render item.

Will convert the MRenderItem to instanced rendering if not already done. The render item should already have it's other properties set (including shader and geometry). A render item converted to instanced rendering will ignore its typical matrix from setMatrix().

A render item marked for sub scene consolidation cannot be instanced and will report failure until it is unmarked for sub scene consolidation.

Parameters
[in]renderItemThe render item to add a new instance to.
[in]transformThe transformation matrix of the new instance.
Returns
The instance ID for the new instance. This ID can be used to change the matrix or remove it. A return value of 0 indicates an error (render item does not support instancing or invalid state). 0 is never a valid instance ID.
MStatus setInstanceTransformArray ( MRenderItem renderItem,
const MMatrixArray matrixArray 
)

Sets the entire instance array for a render item.

Will convert the MRenderItem to instanced rendering if not already done. Any pre-existing instances will be removed. The render item should already have it's other properties set (including shader and geometry). A render item converted to instanced rendering will ignore its typical matrix from setMatrix(). This function is provided as a simpler alternative to addInstanceTransform() for when the ability to update or remove individual instances is not required. However additional instances may still be added via addInstanceTransform() and those may be individually updated or removed.

A render item marked for sub scene consolidation cannot be instanced and will report failure until it is unmarked for sub scene consolidation.

Parameters
[in]renderItemThe render item to set the instance matrix array for.
[in]matrixArrayThe transformation matrix array for all the instances.
Returns
Status code
Status Codes:
MStatus updateInstanceTransform ( MRenderItem renderItem,
unsigned int  instanceId,
const MMatrix transform 
)

Update the instance transform matrix for one instance of a render item.

Parameters
[in]renderItemThe render item to operate on.
[in]instanceIdThe instance ID of the instance to update. This must be a value returned by addInstanceTransform.
[in]transformThe new transformation matrix for the instance.
Returns
Status code
Status Codes:
MStatus removeInstance ( MRenderItem renderItem,
unsigned int  instanceId 
)

Remove one instance of a render item.

Parameters
[in]renderItemThe render item to operate on.
[in]instanceIdThe instance ID of the instance to remove. This must be a value returned by addInstanceTransform.
Returns
Status code
Status Codes:
MStatus removeAllInstances ( MRenderItem renderItem)

Remove all instances for a render item.

This render item will remain set up for instancing and will render nothing until new instances are added.

Parameters
[in]renderItemThe render item to operate on.
Returns
Status code
Status Codes:
MStatus setExtraInstanceData ( MRenderItem renderItem,
const MString parameterName,
const MFloatArray data 
)

Adds an extra stream of instanced data to an instanced render item.

Once a render item has been instanced, additional per-instance data may be bound to a parameter on the shader for that item. Supported shader parameter types for instanced data include: float, float2, float3 and float4. Once a stream of instanced data is specified for a shader parameter, the original value of that parameter will be ignored in favor of the per-instance data specified in this method.

If the render item has not been set up for instancing or if an invalid parameter was specified this method will fail. The size of the data array must be x*numberOfInstances where x is the size of the channel (1-4). If the size is wrong, the method will fail.

More than one stream of extra instance data may be specified for an instanced render item. The number of streams will be limited by the number of texture co-ordinate channels available from the underlying graphics system (and note that the instanced matrix occupies four streams). If too many streams are used then a red error shader will be displayed instead of the expected shader.

Parameters
[in]renderItemThe render item to operate on
[in]parameterNameThe name of the parameter on the shader to fill with the instanced data
[in]dataThe instanced data stream
Returns
Status code
Status Codes:
MStatus setExtraInstanceData ( MRenderItem renderItem,
unsigned int  instanceId,
const MString parameterName,
const MFloatArray data 
)

Set the value for the specified extra instance data stream for a particular instance of the instanced render item.

See setExtraInstanceData(MRenderItem&, const MString&, const MFloatArray&) for a full description of extra instance data streams.

Parameters
[in]renderItemThe render item to operate on
[in]instanceIdThe instance ID of the instance to set the data for
[in]parameterNameThe name of the parameter on the shader to fill with the instanced data
[in]dataThe data for the specific instance
Returns
Status code
Status Codes:
MStatus removeExtraInstanceData ( MRenderItem renderItem,
const MString parameterName 
)

Remove an entire extra instance data stream from the instanced render item.

Parameters
[in]renderItemThe render item to operate on
[in]parameterNameThe name of the parameter associated with the extra instance data stream
Returns
Status code
Status Codes:
MStatus setAllowTransparentInstances ( MRenderItem renderItem,
bool  allow 
)

Instancing is disabled automatically by default when the shader is transparent.

This achieves the best appearance because Maya can sort individual instances.

In some cases, performance is more important than appearance. e.g. particles This method allows to override the default behavior.

Parameters
[in]renderItemThe render item to operate on
[in]allowWhether to allow instancing with transparent shader
Returns
Status code
Status Codes:
const char * className ( )
static

Returns the name of this class.

Returns
Name of this class.

The documentation for this class was generated from the following files:
  • MPxSubSceneOverride.h
  • MPxSubSceneOverride.cpp