Reverse Foot Rig Tool 1.00 For Maya

Another Tool for Maya on cubebrush . I have been meaning to release this one for a while. Although it is very simple in concept this tool is very games setup and performance friendly since it doesn't alter your character skeleton and all its connections are done with Maya nodes(No expressions/No Set Driven Key Animations).  Also its ability to create a mirrored setup very fast is incredibly useful for mirroring animations.

For more info check the documentation

New Market place on Cubebrush

Hey guys, I am moving all of my tools to Cube brush.

You can find the Dynamic Chain setup tool for all Maya versions starting from 2014.

I am releasing the tool for free. However, I would appreciate some contribution if you would like me to keep making tools for free.

Keep posted. There will be more tools added to that page :)

Adding an Animated Gif to a QLabel with Pyside

Time for another tutorial  not for the drag and drop (Got a bit distracted with the inspiration for this tutorial) but for adding an animated gif to a QLabel.

In this example I am loading the file into a QByteArray so we don't keep that GIF in memory. However you can add the GIF file directly to the QMovie as the first argument.

If you can't display the GIF in your own code, double check the qt.conf file and make sure that it is referring to the correct plugins folder. 

PS: If you don't recognise the GIF shown in the tool, you can find the Video here.("You are welcome"). 

import sys
import os
from PySide import QtCore, QtGui
ImagesFolder=os.path.join(os.path.dirname(__file__),'images')

class CucumberGifWidget(QtGui.QLabel):
    def __init__(self, parent=None):
        super(CucumberGifWidget, self).__init__(parent)
        self.setAcceptDrops(True)
        self.setFrameStyle(QtGui.QFrame.WinPanel | QtGui.QFrame.Sunken)
        self.setAlignment(QtCore.Qt.AlignCenter)
        self.setSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.MinimumExpanding)
        
        trashGif= open(os.path.join(ImagesFolder,'cucumber.gif'), 'rb').read()
        self.gifByteArray=QtCore.QByteArray(trashGif)
        self.gifBuffer=QtCore.QBuffer(self.gifByteArray)
        self.movie = QtGui.QMovie()
        self.movie.setFormat('GIF')
        self.movie.setDevice(self.gifBuffer)
        self.movie.setCacheMode(QtGui.QMovie.CacheAll)
        self.movie.setSpeed(100)
        self.setMovie(self.movie)
        self.movie.jumpToFrame(0)

    def dragEnterEvent(self, event):
        if event.mimeData().hasImage():
            event.setDropAction(QtCore.Qt.MoveAction)
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        event.setDropAction(QtCore.Qt.MoveAction)
        if event.mimeData().hasImage():
            if "cucumber" in event.mimeData().text():
                self.movie.start()
                event.source().setParent(None)
                event.source().deleteLater()
            else:
                event.accept()
        else:
            event.ignore()

Drag and drop with Qt and PySide

I have always been using (well at least the past 7 years) QT for creating interfaces for my PySide/PyQt applications. Lately I've decided to dive a bit deeper to create and experiment with more complex behaviours. 

Starting with a convenient behaviour : Drag and Drop.

In the example I am sharing here I re-implemented the drag and drop related methods of a QLabel and a QWidget so we are able to drag the label into the widget. What actually happens is that when we drop the label on  the widget we create another Label with the same information,  it is a Copying action.

TODO: In the upcoming weeks we will add the functionality of re-arranging the labels in the Drop widget and also from one Drop widget to another.
import sys
from PySide import QtCore, QtGui

class InitialCard(QtGui.QLabel):
    def __init__(self, text, parent):
        super(InitialCard, self).__init__(text, parent)
        self.setAutoFillBackground(True)
        self.setFrameStyle(QtGui.QFrame.WinPanel|QtGui.QFrame.Sunken)
        newFont = QtGui.QFont("MsReferenceSansSerif", 10)
        newFont.setBold(False)
        self.setFont(newFont)
        self.setMinimumSize(90, 25)
        self.setMaximumHeight(30)
        self.setAlignment(QtCore.Qt.AlignCenter)
        self.mimeText=self.text()

    def mouseMoveEvent(self, event):
        if not self.text():
            return
        mimeData = QtCore.QMimeData()
        mimeData.setText(self.mimeText)
        drag = QtGui.QDrag(self)
        drag.setMimeData(mimeData)
        drag.exec_(QtCore.Qt.CopyAction | QtCore.Qt.MoveAction, QtCore.Qt.CopyAction)

class CardsDropWidget(QtGui.QWidget):

    def __init__(self, parent):
        super(CardsDropWidget, self).__init__(parent)
        self.setAcceptDrops(True)
        self.contentsVLO = QtGui.QVBoxLayout()
        self.contentsVLO.setAlignment(QtCore.Qt.AlignTop)
        self.setLayout(self.contentsVLO)
    
    def dragEnterEvent(self, event):
        if event.mimeData().hasText():
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasText():
            cardSource=event.source()
            cardText=cardSource.text()
            if not cardSource in self.children():
                newCard = InitialCard(cardText, self)
                self.contentsVLO.addWidget(newCard)
                cardSource.clear()
            else:
                event.ignore()
        else:
            event.ignore()

class MainDialogue(QtGui.QDialog):
    def __init__(self, parent=None):
        super(MainDialogue, self).__init__(parent)
        self.label=InitialCard("initial", self)
        self.lineEdit=QtGui.QLineEdit("Create a Card Here!!")
        self.lineEdit.selectAll()
        self.scrollArea = QtGui.QScrollArea()
        self.scrollArea.setWidgetResizable(True)
        self.scrollContent = CardsDropWidget(self.scrollArea)
        self.scrollArea.setMinimumWidth(150)
        self.scrollArea.setWidget(self.scrollContent)
        self.dialogueLayout=QtGui.QHBoxLayout()
        self.labelLayout=QtGui.QVBoxLayout()
        self.labelLayout.addWidget(self.label)
        self.labelLayout.addWidget(self.lineEdit)
        self.labelLayout.addStretch()
        self.dialogueLayout.addWidget(self.scrollArea)
        self.dialogueLayout.addLayout(self.labelLayout)
        self.setLayout(self.dialogueLayout)
        self.setWindowTitle("Drag and Drop")
        self.setMinimumSize(300, 150)
        self.lineEdit.returnPressed.connect(self.createCardTxt_fn)
        
    def createCardTxt_fn(self):
        cardTxt=unicode(self.lineEdit.text())
        self.label.setText(cardTxt)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = MainDialogue()
    window.show()
    sys.exit(app.exec_())

Battlefield 1!!

Hej Hej, its been a while since I posted here. Its been a very busy year. Moved to another country and joined a new company. Yes Dice EA and I am so excited to share with you the project that I have been working on over there, BattleField 1.

DynamicChainSetupTool is HERE

Happy New Year , I've finally finished the DynamicChainSetupTool I promised :)

 

DOWNLOAD HERE (Cubebrush link)

Maya versions: 2014 - 2016

Place the dynamcChainSetupTool folder in your scripts folder. Run these lines in a python tab in the script editor:

from dynamicChainSetupTool import dynamicChainSetup as dc
dc.show()

 

The tool is a simpler version of the tool I wrote for Crytek and showed in my demo reel.

In the Add Rigging tab you can build the rig with your choice of no. of controllers and a controller shape.

You can also give the rig a prefix, if you don't give it a prefix it will take the name of the start joint as a prefix.

In the nucleus and the hair system drop down menus, you will see a list of all nuclei and hair systems in the scene in case you want to use any of them for your rig.

If you create manually new nucleus or hair system while the tool is open just click refresh to add them to the drop down menus in the UI.

Now you are ready to create the rig, it is a very simple IK behaving like Fk setup. Remember you need ti keep the dynamic curve smooth for best simulation results.

In the Simulation tab, just make sure you have a controller selected and get the nodes that you like.

I don't know about y'all but the times Maya crashed on me trying to walk the attribute editor to select the hair system made me REALLY appreciate this tool.. this is honestly my favorite part about the whole thing.

Another functionality is the baking rig, there you can bake the dynamics simulation onto controllers. Then you have that simulation as animation curves.

This will allow you to fix some collision problems, add another animation layer or make the animation loop-able for a game animation.
All of this without breaking the dynamics rig, which would happen if you bake results on the joints.

In the functions section you can assign an existing or new hair system or nucleus to you rig. 

I hope you enjoy the tool, I will really appreciate if you let me know how it works for you. If you have any questions or problems using it, feel free to post here. Thanks!
 

Ik Spline Advanced Twist Controls - Tutorial

Hello everyone,

I thought I would share some info on the Ik Spline Advanced Twist Controls since I found a few questions about it online and also our new riggers were kind of confused about it 

There are many ways to setup the twist along a spline IK joint chain.. Based on the character you are rigging you can choose what is best for you.

This tutorial assumes you are already familiar with the spline Ik setup and will be focusing only on the advanced twist settings.

First of all, if your aim axis along the joint chain...

 

Read More

Blizzard Loots

While at GDC I attended the Blizzard party along with my colleagues at Crytek.
It was such a great party, met lots of awesome people over there. And as a huge fan of Diablo3 they handled my non stop questioning about the “Reaper of souls” release date for PS3 without  actually giving an answer :(
After giving up on getting an answer, I had a chance to challenge my boss (Chris Evans) at a game of HEARTHSTONE, miraculously I won and got out of the party with these goodies :) woahahhah

GDC 2014: Technical Artist Bootcamp

I’ll be giving a presentation at GDC2014 together with the awesome Vlad Mastilovic from 3lateral. You can DOWNLOAD IT HERE
He’ll be talking about the Ryse facial rigs and I’ll be talking about the character rigging on Ryse.

Technical art continues to march forward and at a faster pace than most disciplines, as it is wide-reaching and wide open. Rigging, Python, pipelines, shaders and unit tests are all known and understood at this time. It’s time to push forward and stretch our legs. Large studios need more powerful toolchains with more professional development environments and small teams need each and every member to be very technically capable. Technical artists know efficiency is at a premium, and a working tool is not good enough anymore; tech artists will learn to focus on a quality user experience when designing tools and workflows. Tech animators will learn quick prototyping techniques of animation systems, which has traditionally been one of the most complex areas to author. More techniques for automating asset processing, fast cinematic workflows, and optimizing asset performance for run-time will be covered.
— GDC