Plugins are one of Maya’s strongest points. As plugins become increasingly complex, they usually call for some form of user interface. However, Maya’s native methods of building user interfaces is quite rudimentary and awkward to use at best. What many people are not aware of is that Maya itself is built using QT, and actually provides a compatible QT Designer. And that designer can result in usable Python code.
In Maya, there are many degrees of curves available. Bézier curves are one of the more favored within Maya due to their intuitive usability and flexibility in comparison to other existing curve types. Bézier curves prove to be a useful asset in any toolbox, as is evident by its extensive use in video games, among other fields. For instance, smooth bézier paths can be used to describe roads, streams, and other environmental objects, or describe the pathway upon which an object should follow. The helpful uses bézier curves provide are endless. If you would like to learn more about bézier curves in the context of games development, Dev.Mag has a fantastic article describing uses and mathematical foundations of the curve.
Firstly, let us briefly discuss how Maya’s bézier curves work on a high level. If you are already comfortable with Maya’s bézier curves, feel free to skip the following section.
One can never have too many frameworks. Whether it be for the learning experience, the enjoyment of a technical challenge, or the need of a reusable platform to build projects upon, frameworks are the backbone of many systems. With that in mind, I would like to share my latest project, ciri.
JSON is a fantastic data-interchange format praised for its legibility, especially in comparison to other common data formats such as XML. When developing plugins for Maya – especially those that export data – JSON is a very compelling format to use. Lucky for us, Python has native support for JSON, and it is very easy to use.
Sometimes Global Hotkeys In C# are not good enough. Sometimes you need to get right down there with the low level events and hook the keyboard yourself. In my recent Fullscreenizer project, I had to do this to detect hotkeys reliably due to games often making their input exclusive and not passing the events on for other applications to detect.
Here is an excerpt from Fullscreenizer’s code that hooks the keyboard at a low level.
I recently picked up an old project and wanted to add some new functionality that would listen for and respond to hotkey combinations even when the application didn’t have focus. After a little searching on the Internet, I came across this helpful post on StackOverflow. The solution in the StackOverflow post made use of the WinAPI RegisterHotKey and UnregisterHotKey functions. Functionality was okay, but was limited to calling the same function even with differing hotkeys. I written my own solution based on the StackOverflow post which fixes this issue. It’s not elegant by any means, but it gets the job done.
Over the last two months or so, I have been working on a project in my free time that overrides Maya’s Viewport 2.0 renderer. A viewport renderer override can be useful to render the scene externally, such as in a game engine. The advantages of this are that you can fully control the rendering so that the result in the viewport matches your game engine in real-time. From a productivity standpoint, this is an amazing plus. Other advantages include, but are not limited to, removing the limitation for the number of light sources natively available within Maya’s built-in viewport renderers. Implementing such a project is no easy task, and it comes with many strange quirks and issues. I will discuss, on a high level, implementation of such a renderer, as well as share some notes on things I’ve learned throughout the project. Some things may be generic to the API whereas others may be specific to renderer overrides. Please note that this is not a tutorial, but is instead intended to provide a direction for you to follow.
It can sometimes be useful to know the radius or range of a light source within Maya. For example, an exporter for a video game could require the radius of a point light and the height of a spotlight to be exported for use in the rendering portion of the game engine, or the same information could even be required for a viewport renderer override in order to compute the lighting. Whatever the case, here’s an easy way to export a radius and range within Maya.
Deformers within Maya can provide users with easy-to-use and intuitive interfaces for modifying, or even animating, low-level components, such as vertices, of geometry. They can be used in many situations, such as providing a starting point for more complex models, keyed for animation, or even to help sculpt and shape geometry, to name a few. Deformers are useful because they are a node in the DAG. This means they affect the geometry at that specific point in time, and can be edited at a later date. They can also be removed like any other node, and the order that the node appears in the graph can have dramatic changes on the resulting geometry. In other programs, such as 3ds Max, they are commonly referred to as Modifiers.
When working with textures in a 3d program, you often find yourself reloading the textures. For example, when creating a 3d model for a video game, you may reload the normal map multiple times, or you may be modifying a diffuse map. Whatever the cause, you will most likely want to see the effect your changes have on the 3d model quickly, so you can get back to tweaking. Unfortunately, programs such as Maya, which this article will focus on, do not provide a quick and easy way to reload textures. The snippets discussed will be from various modules I have previously written, so alone, they will not make complete sense. They will, however, provide you with all information you require to implement this yourself. There are easier ways than will be discussed in this article to reload all textures within the scene. However, when this tool was requested by an artist, I was told it must be able to reload only selected objects’ textures, as well as all textures. Because of this, the solution discussed will include traversal of connections and attributes.