<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Andy Nicholas</title>
	<atom:link href="http://www.andynicholas.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.andynicholas.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Tue, 13 Jul 2010 17:48:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Solutions for Python in XSI (Part 2)</title>
		<link>http://www.andynicholas.com/?p=1016</link>
		<comments>http://www.andynicholas.com/?p=1016#comments</comments>
		<pubDate>Tue, 13 Jul 2010 13:06:36 +0000</pubDate>
		<dc:creator>AndyN</dc:creator>
				<category><![CDATA[Headline]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[XSI]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://www.andynicholas.com/?p=1016</guid>
		<description><![CDATA[This is the second article of two that show solutions to common problems faced when using Python in XSI. 

It discusses a useful way of importing your own Python modules into your plugins.]]></description>
			<content:encoded><![CDATA[<p>This is the second of two articles that will show you solutions to common problems you&#8217;ll face when using Python in XSI. </p>
<h3>Importing Python Modules</h3>
<p>Python modules offer a great way to reuse code. Often you&#8217;ll find that you want to share code between your plugins, especially in a pipeline situation. </p>
<p>XSI isn&#8217;t particularly flexible with how it lets you import modules. At the moment, you have to install your custom written modules in a  folder and use the <b>PYTHONPATH</b> environment variable to point to that location (or add it to the list of paths stored in <b>sys.path</b> at run time.) </p>
<p>Wouldn&#8217;t it be good if we were able to import Python modules so that:</p>
<ul>
<li>You can keep your modules with the plugin that uses them.</li>
<li>You never have to modify your Python path, even when you move the installed plugin to a different location.</li>
<li>The module is only loaded when you need it.</li>
</ul>
<p>Of course, you can just use a standard XSI plugin and register some commands, but there are situations where it might be preferable to use a module. For example:</p>
<ol>
<li>If the functions to be included are very small helper functions that need to be called repeatedly. It might be best to avoid registering commands since they have a slight performance overhead to their execution.</li>
<li>If the functions are non XSI specific and don&#8217;t make much logical sense to be added as XSI commands.</li>
<li>If the functions need to be pass or return Python types such as classes, tuples, sets, lists and dictionaries. There are <a href="http://softimage.wiki.softimage.com/index.php/Python_(XSISDK)#Exposing_a_Python_Object_to_XSI" target="_blank">workarounds</a> for these, but they don&#8217;t really assist with making your code clean and maintainable.</li>
<li>If you want to keep your code hidden, you can put your implementation inside the module and only distribute the .pyc compiled version.</li>
</ol>
<h3>A new way to import modules</h3>
<p>The good news is that you can use the following Python class to mimic the behaviour of an imported module.</p>
<pre><code>
import win32com.client
from win32com.client import constants

import os.path
import imp

<em>#Note: You only need the following line if you're
#putting this code in a file that isn't an XSI plugin.</em>
Application = win32com.client.Dispatch("XSI.Application").Application

class Import:

    def __init__(self, pluginName, moduleName):
        self.pluginName = pluginName
        self.moduleName = moduleName
        self.module = None

    def __getattr__(self, name):
        <em>#Has the module already been loaded?</em>
        if self.module:
            return self.module.__dict__[name]

        <em>#Try and load the module</em>
        path=""
        try:
            path = Application.Plugins(self.pluginName).FileName
        except:
            Application.LogMessage("[Plugin Python Module: " \
                             +self.pluginName+"] " \
                             +"Plugin name doesn't exist or hasn't been loaded" \
                             ,constants.siError)
            return None

        <em>#Import the module</em>
        result = imp.find_module(self.moduleName, [os.path.dirname(path)])
        self.module = imp.load_module(self.moduleName, result[0], \
                                      result[1],result[2])

        if not self.module:
            Application.LogMessage("[Plugin Python Module: " \
                             +self.pluginName+"] " \
                             +"Couldn't load module: "+self.moduleName \
                             ,constants.siError)
            return None

        <em>#Evaluate the attribute</em>
        return self.module.__dict__[name]

</code></pre>
<p>Assuming you&#8217;ve placed the above code into a globally accessible module called <b>xsiimport</b>, then you would use it like this: </p>
<p><em>Note: I&#8217;ve highlighted the specific bits of the code that are relevant</em></p>
<pre><code>
import win32com.client
from win32com.client import constants

<span style="color:#a33"><b>import xsiimport

g_PluginName = "TestCommandPlugin"

<em>#Think of this next line as a normal import statement</em>
testpymodule = xsiimport.Import(g_PluginName, "testpymodule")</b></span>

def XSILoadPlugin( in_reg ):
    in_reg.Author = "Andy"
    <span style="color:#a33"><b>in_reg.Name = g_PluginName</b></span>
    in_reg.Major = 1
    in_reg.Minor = 0

    in_reg.RegisterCommand("MyCommand","MyCommand")
    <em>#RegistrationInsertionPoint - do not remove this line</em>

    return true

def MyCommand_Execute():
    <span style="color:#a33"><b><em>#Use testpymodule as you would any other python module

    #Call functions</em>
    result = testpymodule.DoSomething("inputString")

    <em>#Create classes</em>
    myClassInst = testpymodule.MyClass()</b></span>

</code></pre>
<p>As shown, the easiest way to use this class is to import it from a module located in your standard Python path. As a result this would generally only work in a studio environment where you are able to make sure your art team are working on the same file system and with the same environment variables.</p>
<p>If you intend to distribute your plugin, then the alternative is to copy the class definition to each of your plugins that needs to use it. While untidy, the benefits it offers are probably worth it, but I&#8217;ll leave it to you to decide.</p>
<h3>How it works</h3>
<p>So if you&#8217;re interested in what&#8217;s happening under the hood, I&#8217;ll briefly run through what&#8217;s happening.</p>
<p>This line in our plugin:</p>
<pre><code>
testpymodule = xsiimport.Import(g_PluginName, "testpymodule")</b></span>

</code></pre>
<p>doesn&#8217;t actually do anything apart from create an instance of the Import class. In its constructor, it just stores the name of the plugin and the name of the module we want to import.</p>
<p>The reason the class doesn&#8217;t load the module at this stage is because the plugin probably hasn&#8217;t been registered with XSI yet (don&#8217;t forget, we&#8217;re still running code in global scope here). Therefore, we can&#8217;t ask XSI for the file path of the plugin using the Application.Plugins collection.</p>
<p>The module only gets loaded when we ask it to do something in our command like this:</p>
<pre><code>
    <em>#Call functions</em>
    result = testpymodule.DoSomething("inputString")

    <em>#Create classes</em>
    myClassInst = testpymodule.MyClass()</b></span>

</code></pre>
<p>At this point, the <b>__getattr__</b> member function of the <b>Import</b> class is called. It checks to see if the module has already been loaded and loads it if it hasn&#8217;t. Either way, the class returns the attribute that is asked for, where it is either called as a function or used to create an instance of a class (as shown above).</p>
<p>This delayed loading mechanism is the reason that this system works and why it&#8217;s so robust. All other methods that I&#8217;ve tried suffer because the plugin isn&#8217;t loaded, which forces you to <a href="http://softimage.wiki.softimage.com/index.php/Python_Custom_Modules_(XSISDK)" target="_blank">import modules inside function declarations</a> (which feels a bit hacky)</p>
<p>To load the module, I&#8217;m using the <b>imp</b> module. It exposes the lower level commands inside the import mechanism. By calling <b>imp.find_module()</b> followed by <b>imp.load_module()</b>, it forces a reload of the module and flushes any cache stored for that module. Generally, this behaviour is desirable as XSI tends to be quite aggressive with it&#8217;s caching.</p>
<p>And in case you&#8217;re wondering. Yes. This method for importing works fine with the callback mechanism in the <a href="http://www.andynicholas.com/?p=1014">previous article</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andynicholas.com/?feed=rss2&amp;p=1016</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Solutions for Python in XSI (Part 1)</title>
		<link>http://www.andynicholas.com/?p=1014</link>
		<comments>http://www.andynicholas.com/?p=1014#comments</comments>
		<pubDate>Thu, 08 Jul 2010 13:06:04 +0000</pubDate>
		<dc:creator>AndyN</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[XSI]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://www.andynicholas.com/?p=1014</guid>
		<description><![CDATA[This article is the first of two that will show you solutions to a couple of common problems you'll face when using Python in XSI. 

Here we look at passing functions to PPGs to be used as PPG logic. Something simple in other scripting languages, but harder in Python.]]></description>
			<content:encoded><![CDATA[<p>This article is the first of two that will show you solutions to a couple of common problems you&#8217;ll face when using Python in XSI. </p>
<h3>How to pass functions to PPG logic in Python</h3>
<p>When making user interfaces in XSI, I find that I often need to create custom properties on the fly, rather that fully self-installed custom property plugins. When doing this, I usually need to pass callback functions to the PPGLogic attribute so that XSI knows what to do when a button is clicked or a value changes. In JScript, this is simply done using the toString() method of the JScript function object, like this:</p>
<pre><code>
function MyJScriptCommand_Execute(  )
{
    prop = XSIFactory.CreateObject("CustomProperty")
    prop.AddParameter2("myValue",siInt4,0,0,100,0,100,
                            siClassifUnknown,
                            siPersistable | siKeyable);

    layout = prop.PPGLayout;
    layout.AddItem("myValue");
    layout.AddButton("myButton");

    layout.language="JScript"
    <span style="color:#a33"><b>layout.logic=myValue_OnChanged.toString()+
                     myButton_OnClicked.toString();</b></span>
    InspectObj(prop);
    return true;
}

function myValue_OnChanged()
{
    LogMessage("myValue was changed");
}

function myButton_OnClicked()
{
    LogMessage("myButton was clicked");
}

</code></pre>
<p>Despite the flexibility that Python offers as a language, it doesn&#8217;t have a mechanism able to do this. So we need to find another method.</p>
<h3>Triple Quoted Strings</h3>
<p>One common way to do it is to write your functions inside a triple quoted string. Here&#8217;s the Python equivalent of the above code:</p>
<pre><code>
def MyPythonCommand_Execute(  ):

    prop = XSIFactory.CreateObject("CustomProperty")
    prop.AddParameter2("myValue",constants.siInt4,0,0,100,0,100,
                            constants.siClassifUnknown,
                            constants.siPersistable | constants.siKeyable)

    layout = prop.PPGLayout
    layout.AddItem("myValue")
    layout.AddButton("myButton")

    layout.language="Python"
    <span style="color:#a33"><b>layout.logic='''
def myValue_OnChanged():
    LogMessage("myValue was changed")

def myButton_OnClicked():
    LogMessage("myButton was clicked")
'''</b></span>
    Application.InspectObj(prop)
    return true;

</code></pre>
<p>This is perfectly acceptable and works fine, but it does have a few drawbacks:</p>
<ul>
<li>It makes the code look ugly and less readable. Python is formatted in a specific way due to the indentation being linked to the syntactical interpretation. Putting code inside a triple quoted string goes somewhat against this ideal.</li>
<li>Most text editors will not show the syntax highlighting for the callback code, and will highlight it as a string. This is a minor problem but can be annoying, particularly if you&#8217;re building a complex string with escaped characters.</li>
<li>All the code inside the triple quotes is executed in a new scope. This means that any global constants, helper functions, or module imports will have to be repeated inside the triple quoted section. This can lead to a lot of code duplication, which is obviously a bad thing.</li>
</ul>
<h3>Using the Logic File attribute</h3>
<p>It would be fair to say that the triple quoted string method isn&#8217;t particularly convenient. Are there any other ways that we can do this?</p>
<p>Yes. If you look at the PPGLayout attributes, you&#8217;ll see that we have the ability to specify a PPG logic file. This is a file in which we can put all our callback functions, and as long as we tell XSI where to find it, everything should work fine. For example:</p>
<pre><code>
def MyPythonCommand_Execute(  ):

    prop = XSIFactory.CreateObject("CustomProperty")
    prop.AddParameter2("myValue",constants.siInt4,0,0,100,0,100,
                            constants.siClassifUnknown,
                            constants.siPersistable | constants.siKeyable)

    layout = prop.PPGLayout
    layout.AddItem("myValue")
    layout.AddButton("myButton")

    layout.language="Python"
    <span style="color:#a33"><b>layout.SetAttribute(constants.siUILogicFile,
                        "C:\\Workgroup\\Application\\Plugins\\PPGCallbacks.py")</b></span>
    Application.InspectObj(prop)

</code></pre>
<p>&#8230;and in a separate file called PPGCallbacks.py</p>
<pre><code>
def myValue_OnChanged():
    LogMessage("myValue was changed")

def myButton_OnClicked():
    LogMessage("myButton was clicked")

</code></pre>
<p>This certainly gets around the problem of syntax highlighting, but it still means we have to redeclare global constants, helper functions, and reimport modules. It also gives us two extra problems of having to hardcode the location of the logic file, and having to make sure that the plugin file and the callback file are always installed together. If anything goes wrong with either of those, you&#8217;re not going to know about it until you open the PPG and press a button or change a value.</p>
<p>Okay, why not eliminate the extra file and just point it at the original script? </p>
<pre><code>
def MyPythonCommand_Execute(  ):

    prop = XSIFactory.CreateObject("CustomProperty")
    prop.AddParameter2("myValue",constants.siInt4,0,0,100,0,100,
                            constants.siClassifUnknown,
                            constants.siPersistable | constants.siKeyable)

    layout = prop.PPGLayout
    layout.AddItem("myValue")
    layout.AddButton("myButton")

    layout.language="Python"
    <span style="color:#a33"><b>layout.SetAttribute(constants.siUILogicFile,
                 "C:\\Workgroup\\Application\\Plugins\\MyPythonPlugin.py")</b></span>
    Application.InspectObj(prop)

<span style="color:#a33"><b>def myValue_OnChanged():
    LogMessage("myValue was changed")

def myButton_OnClicked():
    LogMessage("myButton was clicked")</b></span>

</code></pre>
<p>That&#8217;s much better. We don&#8217;t need to manage two files and we can put all our callback code in the same file as the PPG definition. It starts behaving a lot like a self-installed custom property, although we still have the problem of hard coding the path.</p>
<h3>Using XSI&#8217;s plugin registry</h3>
<p>The solution is to look up the path to the current plugin file using Application.Plugins. </p>
<p>Let&#8217;s look at the details of how this works.</p>
<p>Application.Plugins is a collection of XSI plugin objects. We can retrieve any particular one by asking for it by name. This is the one we declared it with in the registration function.</p>
<pre><code>
def XSILoadPlugin( in_reg ):
    in_reg.Author = "Andy"
    in_reg.Name = <span style="color:#a33"><b>"My Python Plugin"</b></span>
    in_reg.Major = 1
    in_reg.Minor = 0

    in_reg.RegisterCommand("MyPythonCommand","MyPythonCommand")
    #RegistrationInsertionPoint - do not remove this line

    return true

</code></pre>
<p>By using this name to index into the plugin collection, XSI will return us a Plugin object:</p>
<pre><code>
pluginObject = Application.Plugins("My Python Plugin")

</code></pre>
<p>Once we have the plugin object we can ask it for its filename:</p>
<pre><code>
LogMessage(Application.Plugins("My Python Plugin").FileName)

# INFO : C:\Workgroup\Application\Plugins\MyPythonPlugin.py

</code></pre>
<p>So to set the logic file to point to the current plugin, we can just do this:</p>
<pre><code>
layout.SetAttribute(constants.siUILogicFile,
                    Application.Plugins("My Python Plugin").FileName)

</code></pre>
<p>To obey the rule I mentioned earlier about not defining the same thing twice, we can define the plugin name as a global variable right at the top of the script. The final script looks like this:</p>
<pre><code>
import win32com.client
from win32com.client import constants

<span style="color:#a33"><b>g_pluginName = "My Python Plugin"</b></span>

def XSILoadPlugin( in_reg ):
    in_reg.Author = "Andy"
    <span style="color:#a33"><b>in_reg.Name = g_pluginName</b></span>
    in_reg.Major = 1
    in_reg.Minor = 0

    in_reg.RegisterCommand("MyPythonCommand","MyPythonCommand")
    #RegistrationInsertionPoint - do not remove this line

    return true

def MyPythonCommand_Execute(  ):

    prop = XSIFactory.CreateObject("CustomProperty")
    prop.AddParameter2("myValue",constants.siInt4,0,0,100,0,100,
                            constants.siClassifUnknown,
                            constants.siPersistable | constants.siKeyable)

    layout = prop.PPGLayout
    layout.AddItem("myValue")
    layout.AddButton("myButton")

    layout.language="Python"
    <span style="color:#a33"><b>layout.SetAttribute(constants.siUILogicFile,
                        Application.Plugins(g_pluginName).FileName)</b></span>
    Application.InspectObj(prop)

def myValue_OnChanged():
    LogMessage("myValue was changed")

def myButton_OnClicked():
    LogMessage("myButton was clicked")

</code></pre>
<p>That&#8217;s all there is to it. Now we have a workable strategy that has the following advantages:</p>
<ul>
<li>Tidy code</li>
<li>Full syntax highlighting</li>
<li>All the code is in a single file</li>
<li>All the constant definitions, helper functions, and imports only need to be written once</li>
</ul>
<p>Note that the callback code is still being executed in a different context. There&#8217;s no way around that. This means that changes to the values of global variables will not get passed through to the callback code. Global constants work fine because they are declared in global scope and don&#8217;t change.</p>
<p>In the second installment of this article, I&#8217;ll be showing you how to load python modules that are specific to your plugin using a similar system.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andynicholas.com/?feed=rss2&amp;p=1014</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Nested ICE compound hell</title>
		<link>http://www.andynicholas.com/?p=1048</link>
		<comments>http://www.andynicholas.com/?p=1048#comments</comments>
		<pubDate>Sun, 04 Jul 2010 17:33:52 +0000</pubDate>
		<dc:creator>AndyN</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[ICE]]></category>
		<category><![CDATA[XSI]]></category>
		<category><![CDATA[compounds]]></category>

		<guid isPermaLink="false">http://www.andynicholas.com/?p=1048</guid>
		<description><![CDATA[Exporting ICE compounds. What could be simpler? 

Well, as it turns out, quite a lot. Especially if you forget to tick a certain checkbox...]]></description>
			<content:encoded><![CDATA[<p>It seems to be a general rule that just when you think you know a bit of software, it comes back to bite you on the ass. This time, ICE threw up a surprise when I went to import a compound. It seemed to come in okay, but it complained in the script window. It couldn&#8217;t find a compound that was used inside the one I&#8217;d just imported.</p>
<p>I had assumed that XSI embeds the definition of compounds used within exported compounds. By default, this isn&#8217;t the case, and I had forgotten that I had renamed the internal compound to something else.</p>
<p>So it turns out that there&#8217;s an innocent little option on the Export Compounds dialog called &#8220;Embed internal compounds&#8221;. It&#8217;s off by default, and I&#8217;d strongly recommend turning it on every time you export your compounds.</p>
<div align="center">
<a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2010/07/SaveDialog.gif" class="lightview" rel="gallery[1048]" title="SaveDialog"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2010/07/SaveDialog-300x219.gif" alt="SaveDialog" title="SaveDialog" width="300" height="219" class="aligncenter size-medium wp-image-1055" /></a></p>
</div>
<p>If you don&#8217;t tick that little box, XSI only stores the names of the nested compounds. That means that if any of the internal compounds get moved, renamed, or deleted, your main compound will no longer work. </p>
<p>What&#8217;s potentially worse, is that if you update one of the nested compounds with a slightly different functionality, then the behaviour of your main compound will change too. This is particularly bad because this would happen invisibly to you. No warning, no error messages, no nothing.</p>
<p>Aha, you say, but what if there&#8217;s a bug in that nested compound? Isn&#8217;t it desirable that fixing it will propagate to any other compounds that use it? Yep, sure that&#8217;s handy. However, if you&#8217;re working in a pipeline and store your compounds in an SVN, your compound has just changed behaviour and it has no associated version checked in to allow you to roll back if needed. It makes it impossible to track versions.</p>
<p>In short, if you don&#8217;t tick this innocuous little box, you&#8217;ll end up creating compounds with a spiders web of dependencies on each other. You could end up with a situation reminiscent of Windows <a href="http://en.wikipedia.org/wiki/DLL_hell" target="_blank">DLL hell</a>.</p>
<p>Believe it or not, it&#8217;s actually possible to create infinite recursion with circular references.  If you make one, it&#8217;ll export okay, but when you drag it back in, XSI will hang as it tries to add nodes inside of themselves. Admittedly, this is a bit of a contrived situation, but it should serve as a warning that not embedding your compounds is a bad bad idea.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andynicholas.com/?feed=rss2&amp;p=1048</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Rotating Points With a 3&#215;3 Matrix</title>
		<link>http://www.andynicholas.com/?p=911</link>
		<comments>http://www.andynicholas.com/?p=911#comments</comments>
		<pubDate>Sun, 09 May 2010 13:30:27 +0000</pubDate>
		<dc:creator>AndyN</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Maths]]></category>
		<category><![CDATA[Matrix]]></category>
		<category><![CDATA[points]]></category>
		<category><![CDATA[rotation]]></category>
		<category><![CDATA[Vector]]></category>

		<guid isPermaLink="false">http://www.andynicholas.com/?p=911</guid>
		<description><![CDATA[How do 3x3 matrices rotate and scale points?

This is the second installment in a series of articles to help explain and develop intuition surrounding what is sometimes mistakenly perceived to be a difficult subject.]]></description>
			<content:encoded><![CDATA[<div class="retrospective">
<em>This article follows directly on from the previous one in the VFX Math series: <a href="http://www.andynicholas.com/?p=861">How to Read a 3×3 Matrix</a>. If you haven&#8217;t read it yet, do so before reading this one as it introduces you to some important concepts that this article relies on.</p>
<p>Both articles are written informally to assist with clarity and so aren&#8217;t mathematically precise in their notation. That comes later once understanding and intuition has been developed.</em></div>
<h3>Introduction</h3>
<p><a href="http://www.andynicholas.com/?p=861">Previously</a>, we looked at how a matrix can be thought of as being made up of three axes. It was an easy way to help visualise what the numbers in the matrix represented. We&#8217;ll continue using that idea in this article to see how 3&#215;3 matrices are able to rotate and scale points in space. </p>
<p>If you&#8217;re new to some of these concepts and find that you get lost halfway through, it&#8217;s often a good idea to try leaving it for a short period of time and revisiting later. You should find it a lot easier to understand on subsequent readings. If you still find that a particular section is hard to understand, please feel free to let me know in the comments, and I&#8217;ll either modify the article, or post an explanation in reply.</p>
<h3>Defining a point</h3>
<p>So starting with the basics; what do we mean by a point in space? Usually, we express a position using 3D cartesian coordinates, which has three components X, Y, and Z.</p>
<div align="center">
<img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2010/05/RotVec_pxyz.gif" alt="RotVec_pxyz" title="RotVec_pxyz" width="148" height="28" class="aligncenter size-full wp-image-974 noborder" />
</div>
<p>For example:</p>
<div align="center">
<img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2010/05/RotVec_p123.gif" alt="RotVec_p123" title="RotVec_p123" width="148" height="28" class="aligncenter size-full wp-image-964 noborder" />
</div>
<p>describes a point one unit along the X axis, two units along the Y, and three units along the Z axis.</p>
<p>For now, let&#8217;s just consider this point:</p>
<div align="center">
<img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2010/05/RotVec_p111.gif" alt="RotVec_p111" title="RotVec_p111" width="148" height="28" class="aligncenter size-full wp-image-962 noborder" />
</div>
<p>Why? Because it makes it much easier to observe what&#8217;s happening. The following animation shows how the point is reached by travelling along each axis.</p>
<p><object width="590" height="472"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=10846827&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=10846827&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="590" height="472"></embed></object><br /></p>
<p>You should notice that at any time during the video, the point position (shown in white) is equal to the sum of the yellow numbers that appear along it&#8217;s route. Just to clarify; by this I mean that all the X components of the yellow numbers along the X, Y, and Z axes are added to make the X component of the final point position, and similarly for the Y and Z components.</p>
<p>So looking at the video again, the first number of each yellow set of numbers are added to become the first number of the position, the second are added to form the second, and the third make up the third. Play it back and stop it when the point is halfway along any of the axes and this should be clearer to see.</p>
<p>This all means that the final position [ 1, 1, 1 ] is made up like this:</p>
<div align="center">
<img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2010/05/RotVec_p111sum.gif" alt="RotVec_p111sum" title="RotVec_p111sum" width="148" height="120" class="aligncenter size-full wp-image-963 noborder" />
</div>
<p>So we can see that in this case, a point position at [ 1, 1, 1 ] is just made from adding the end point positions of each axis. </p>
<h3>Local Space versus World Space</h3>
<p>The following clip shows this same point position [ 1, 1, 1 ] which has been  <em>transformed</em> by a matrix that has a 30 degree rotation about the Z axis. </p>
<p><object width="590" height="472"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=10846884&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=10846884&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="590" height="472"></embed></object><br /></p>
<p>Again, we can see that at any stage during the animation, the point position is made up of the sum of the axes it has travelled along. In a way, it&#8217;s more obvious than the previous clip, since here the numbers are more identifiable as forming the sum of the final point position.</p>
<p>The final point position is given by:</p>
<div align="center">
<img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2010/05/RotVec_prot30sum.gif" alt="RotVec_prot30sum" title="RotVec_prot30sum" width="349" height="135" class="aligncenter size-full wp-image-971 noborder" />
</div>
<p>Remember, these point positions being added together are just the positions of the end points of each axis in world space.</p>
<div class="techdetail">
<h3>Technical Detail</h3>
<p>The important thing to realise is that we now have two coordinate systems. An unchanged <em><strong>world</strong></em> coordinate system (which you can see in the above video represented by thin colored lines that lie along the world X, Y, and Z axes) and a rotated <em><strong>local</strong></em> coordinate system (represented by the thick colored lines with arrows).</p>
<p>The <em><strong>local</strong></em> position of the point relative to the three axes hasn&#8217;t changed and is still [ 1, 1, 1 ]. We say that, relative to the axes shown, this position is in local space. The end position shown however is [ 0.37, 1.37, 1.0 ] and is relative to the stationary world axes. We say that this position is given in world space.</p>
<p>If it helps, you can think of the axes as an object in your 3D scene. Rotating the object means that it&#8217;s coordinate system is rotated too. It no longer aligns to the world coordinate system. Positions of points or vertices that belong to the geometry of the object will always be stored in local space, and you can usually see these positions by selecting them in the viewport. Some 3D software allows you to see the position in different coordinate spaces, so you may need to switch from &#8220;World&#8221; or &#8220;Global&#8221; modes to &#8220;Object&#8221; or &#8220;Parent&#8221; modes to see it in local space.
</p></div>
<p>Just for show, lets look at what happens when we animate the rotation of the matrix. You can think of this as representing what happens when you interactively rotate an object in your 3D application. For clarity, the clip shows the animation first, and then overlays the resulting point position.</p>
<p><object width="590" height="472"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=10846856&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=10846856&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="590" height="472"></embed></object><br /></p>
<p>Again, pause the animation at any moment in time, and you&#8217;ll see that the final point position is made up of the sum of the yellow numbers along the axes.  (Note: if it doesn&#8217;t add up exactly, it&#8217;ll be due to rounding issues of the display)</p>
<p>The <a href="http://www.andynicholas.com/?p=362&#038;page=2">next page</a> of this article goes on to look at the more general case.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andynicholas.com/?feed=rss2&amp;p=911</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>XSI Tab Menu</title>
		<link>http://www.andynicholas.com/?p=913</link>
		<comments>http://www.andynicholas.com/?p=913#comments</comments>
		<pubDate>Sun, 21 Feb 2010 23:56:42 +0000</pubDate>
		<dc:creator>AndyN</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[XSI]]></category>

		<guid isPermaLink="false">http://www.andynicholas.com/?p=913</guid>
		<description><![CDATA[A tool free to download for XSI, that mimics the Tab menu from Houdini and Nuke. 

A great way to speed up your workflow.]]></description>
			<content:encoded><![CDATA[<h3>Description</h3>
<p>The XSI Tab Menu tool lets you accelerate your workflow by allowing easy access to run common commands and add nodes to your ICE tree and Render tree. It does this using a pop up window (accessed by hitting &lt;Tab&gt;) which temporarilly captures keyboard input to determine what to do. You&#8217;ll probably recognise that this is a similar functionality to that found in Houdini and Nuke.</p>
<h3>Installation</h3>
<p>The plugin is provided as an XSI Add-On file, and you can simply drag and drop the download link into XSI to install it. Alternatively, download the file, and then drag and drop the file into XSI, or use the <i>File -> Add-On -> Install</i> menu option.</p>
<p><a href="/apnwp/wp-content/uploads/2010/02/fxnut_TabMenu.xsiaddon"><img class="downloadicon" src="http://www.andynicholas.com/apnwp/wp-content/themes/arthemia/images/download.gif" onmouseover="this.src='http://www.andynicholas.com/apnwp/wp-content/themes/arthemia/images/download_o.gif'" onmouseout="this.src='http://www.andynicholas.com/apnwp/wp-content/themes/arthemia/images/download.gif'" alt="Download..." width="92" height="20"/></a> XSI&nbsp;Tab&nbsp;Menu V1.3 (32Kb)</p>
<h4>Versions</h4>
<p><i>1.0: Initial release</i><br />
<i>1.1: Fixed issue with using Tab Menu in alternative layouts</i><br />
<i>1.2: Tab menu now always appears in new window (avoids problem with property pages embedded in the viewport). Fixed keyboard conflict with PickObject() command. Now allows closing of menu by hitting escape.</i><br />
<i>1.3: Fixed conflict with &#8216;B&#8217; key Bounding Box Manipulator tool.</i></p>
<h3>Getting Started</h3>
<p>Once you&#8217;ve installed the add-on, pressing &lt;Tab&gt; should make the Tab Menu appear. Pressing &lt;Tab&gt; again will close it. If the window does not appear, try refreshing your plugins or restarting XSI.</p>
<p>Take a look at this video to give yourself some idea of how you can speed up your workflow. (It might help to go full screen so you can read the text on the Tab Menu a bit easier)</p>
<p><object width="590" height="472"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9716724&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=9716724&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="590" height="472"></embed></object><br /></p>
<p>Give it a go yourself by following the instructions below.</p>
<p><i>Note that if you ever need to close the Tab Menu, just press &lt;Tab&gt; and the window will disappear. If you close the window with the mouse, then the menu will still be capturing the keyboard input, and you&#8217;ll need to press &lt;Tab&gt; again to resume using the normal XSI keyboard shortcuts.</i></p>
<p>Try typing the following:</p>
<pre>&lt;Tab&gt; g &lt;Enter&gt;</pre>
<p>That should have created a new Grid polymesh in your scene. Now type:</p>
<pre>&lt;Tab&gt; e &lt;Enter&gt;</pre>
<p>That will have just created a new point cloud and got it emitting particles from your grid. Try this:</p>
<pre>&lt;Tab&gt; i &lt;Enter&gt;</pre>
<p>You should see the ICE tree editor appear in the lower part of the XSI layout. (This is assuming you&#8217;re using the default 4-view layout of XSI). Check that the point cloud is still selected and refresh the ICE tree editor to view it&#8217;s tree.</p>
<p>This bit is important. Click inside the ICE tree editor. This tells the Tab Menu to change context to the ICE tree, and means that you are now in ICE node creation mode. To check this works, type:</p>
<pre>&lt;Tab&gt; setpc &lt;Enter&gt;</pre>
<p>That should have created a Set Particle Color node in your ICE tree.</p>
<h3>Contexts</h3>
<p>The XSI Tab Menu has 3 different contexts: Main, ICE Tree, and Render Tree. You can see which context you&#8217;re currently in by looking at the top of the Tab Menu window. This tells you if you&#8217;re going to be running commands in the main workspace, or if you are going to be adding nodes to your currently viewed ICE or Render tree.</p>
<div align="center"><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2010/02/XSITabMenu.jpg" class="lightview" rel="gallery[913]" title="XSI Tab Menu"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2010/02/XSITabMenu-300x122.jpg" alt="XSI Tab Menu" title="XSI Tab Menu" width="300" height="122" class="aligncenter size-medium wp-image-920" /></a><br/><i>Tab Menu layout (click to enlarge)</i></div>
<h3>How does it work?</h3>
<p>So you&#8217;re probably wondering how do you figure out what to type? It&#8217;s actually quite simple. The easiest way to understand it is to follow it step by step:</p>
<p><i>Note: If you make a mistake, you can either press &lt;Backspace&gt; to undo the last key press, or press &lt;Tab&gt; to cancel entirely and start again.</i></p>
<ol>
<li>Click in the ICE tree editor (in case it&#8217;s lost focus), press &lt;Tab&gt; and then type the letter &#8216;g&#8217;. The Tab Menu window will offer the suggestion &#8220;Generate 3D Point Grid&#8221;. This is the first option available to you (alphabetically) based on the first letter.<br/><br/></li>
<li>Now type the letter &#8216;e&#8217;. The suggestion remains the same as it is still consistent with the letters you&#8217;ve typed so far. Note that at any stage you can press &lt;Enter&gt; to create the node indicated by the current suggestion, or you can hit &lt;Tab&gt; to cancel.<br/><br/></li>
<li>Type the letter &#8216;t&#8217;. Now the suggestion has changed to &#8220;Get Angle Between&#8221;.<br/><br/></li>
<li>Type the letter &#8216;p&#8217;. The suggestion reads &#8220;Get Particle Age&#8221;, although the text above it just reads &#8220;Get P&#8221;. This is because there are two possible letters that can go after &#8216;p&#8217; according to the nodes available.<br/><br/></li>
<li>Now type &#8216;o&#8217;. The suggestion reads &#8220;Get Point ID&#8221; and so does the text above it. This means that there are no more options available. It doesn&#8217;t matter what you type, the suggestion will never change.<br/><br/></li>
<li>Press &lt;Backspace&gt; to take back the &#8216;o&#8217; you just typed. The suggestion should have returned to &#8220;Get Particle Age&#8217;<br/><br/></li>
<li>Here&#8217;s where it gets interesting. Press &#8216;a&#8217;. You&#8217;ll notice that the upper text just jumped to read &#8220;Get Particle&#8221;. This means that the Tab Menu has auto-completed the rest of the word &#8220;Particle&#8221; for you as there are no other options within that word that are available. The next letter you type will dictate what comes after the word &#8220;Particle&#8221; so there is no need to type &#8220;rticle&#8221; to finish the word.<br/><br/></li>
<li>Pressing &#8216;c&#8217; will cause another bit of auto-completion. This time it suggests &#8220;Get Particle Collision Location&#8221;, with the upper text reading &#8220;Get Particle Col&#8221;.<br/><br/></li>
<li>Pressing &#8216;o&#8217; again will show the final suggestion of &#8220;Get Particle Color&#8221;. Pressing &lt;Enter&gt; will create this node. Alternatively you can press &lt;Backspace&gt; to go back and try some other key presses to see how they take you between choices.<br/><br/></li>
</ol>
<p>The approach I take when using this tool is to watch the upper text when typing. You&#8217;ll notice when auto-completion occurs and then you can continue typing the rest of the command/node after. It doesn&#8217;t take long to get extremely fast and efficient at remembering the sequences, and you&#8217;ll make a few jaws drop around you if you can get good at it.</p>
<h3>Limitations</h3>
<p>There are three fairly trivial limitiations you need to know about. Firstly, the context sensitivity for detecting if we&#8217;re in the ICE tree editor, the render tree, or the main viewport is reliant on embedded windows (i.e. in one of the A, B, C, or D viewports). In other words, if you press &#8216;7&#8242; to create a floating render tree window, the Tab Menu will be unable to figure out that context.</p>
<p>Secondly, the &lt;Tab&gt; key by default is used by XSI to &#8220;Show Next Manipulator&#8221;. This usually means that pressing &lt;Tab&gt;will cause XSI to cycle between translation, rotation and scale manipulators. The Tab Menu overrides this functionality, so if you use it a lot, you&#8217;ll need to remap it to another key.</p>
<p>The final limitation is to do with the fact that the Tab Menu relies on three configuration files to specify the commands and nodes available. This means that if you create and register your own ICE tree or render tree compounds, then they won&#8217;t be available as a Tab Menu shortcut until you manually add them to the configuration files. The reason it was done like this was to give minimal delay to you when loading the Tab Menu plugin. If it had to scan (as XSI has to) then there would potentially be a few seconds extra delay when starting up or reloading plugins. </p>
<h3>Adding your own command shortcuts</h3>
<p>The good news is that it&#8217;s very easy to add your own commands to this system. There are three text files located in the same directory as the plugin called:</p>
<p>Main_TabDefinitions.txt<br />
ICE_TabDefinitions.txt<br />
Render_TabDefinitions.txt</p>
<p>From the names, you can see that each text file describes each different context that the Tab Menu supports. If you open the &#8220;Main_TabDefinitions.txt&#8221; file, you&#8217;ll see that each command is contained on it&#8217;s own line and is of the form:</p>
<p><code><br />
&lt;<i>command shortcut</i>&gt;,&lt;<i>python script line to execute</i>&gt;<br />
&nbsp;<br />
</code></p>
<p>So if you look at the first line, you&#8217;ll see the shortcut used to create a cone:</p>
<p><code><br />
Cone,Application.CreatePrim("Cone", "MeshSurface", "", "")<br />
&nbsp;<br />
</code></p>
<h3>Adding your own ICE and Render tree node shortcuts</h3>
<p>For defining shortcuts for the ICE and Render tree, the command that adds nodes needs to be told which tree to add them to. This is done using the symbol %TREE% in the text. This is automatically replaced at runtime with the correct tree that is being currently viewed.</p>
<p>So for example, the shortcut to add a Phong node is as follows (without the line break):</p>
<p><code><br />
Phong, Application.CreateShaderFromPreset("$XSI_DSPRESETS\\Shaders\\Material\\<br />
Phong.Preset", "%TREE%", "")<br />
&nbsp;<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.andynicholas.com/?feed=rss2&amp;p=913</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>How to Read a 3&#215;3 Matrix</title>
		<link>http://www.andynicholas.com/?p=861</link>
		<comments>http://www.andynicholas.com/?p=861#comments</comments>
		<pubDate>Sun, 17 Jan 2010 22:07:35 +0000</pubDate>
		<dc:creator>AndyN</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Maths]]></category>
		<category><![CDATA[Matrix]]></category>
		<category><![CDATA[rotation]]></category>

		<guid isPermaLink="false">http://www.andynicholas.com/?p=861</guid>
		<description><![CDATA[Never quite understood what a 3x3 matrix is? 

This is an introduction to help explain and develop intuition surrounding what is sometimes mistakenly perceived to be a difficult subject.]]></description>
			<content:encoded><![CDATA[<p>Matrices are simple but like anything they take a bit of getting used to. I decided to write this article to help newcomers understand a bit more about them.</p>
<p>It is a summary of an explanation I&#8217;ve frequently used to develop intuition surrounding matrices. I&#8217;ll be assuming very little prior knowledge apart from that you are familiar with 3D applications (it&#8217;s not strictly necessary, but the analogies will make more sense). By the end, I&#8217;m hoping that you can look at a matrix and have a fair idea what it represents. It&#8217;s not an approach I&#8217;ve often seen, but try following it and see if it makes sense to you.</p>
<h3>Introduction</h3>
<p>A 3&#215;3 matrix is used by a 3D application to describe the orientation and a scale of an object in space. (Note that if you want to include the object&#8217;s position, then you need a 4&#215;4 matrix, but we don&#8217;t want to go there yet.)</p>
<p>It is made up of 9 numbers arranged like this:</p>
<div align="center">
<img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/10/ReadAMatrix_Identity.gif" alt="ReadAMatrix_Identity" title="ReadAMatrix_Identity" width="127" height="77" class="aligncenter size-full wp-image-886 noborder" /></div>
<p>This particular 3&#215;3 matrix is known as the &#8220;identity&#8221; matrix. We have zero rotation and a scale of 1. It doesn&#8217;t do anything to a point in space, no rotation or scale, so it&#8217;s a good place to start.</p>
<p>Okay, so this is the important bit. Instead of looking at this matrix as a bunch of numbers, let&#8217;s think about it as representing the axis icon in the corner of your XSI/Houdini/Maya viewport.</p>
<div align="center">
<img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/10/AxisIcon.jpg" alt="AxisIcon" title="AxisIcon" width="300" height="249" class="aligncenter size-full wp-image-895" /></a></div>
<p>The first line of the matrix represents the X axis, the second line the Y axis, and the final line the Z axis. This makes more sense when we think of the end of each line of the matrix being a point in space. This means that each axis looks like this.</p>
<div align="center"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/10/ReadAMatrix_VecIdentity.gif" alt="ReadAMatrix_VecIdentity" title="ReadAMatrix_VecIdentity" width="162" height="86" class="aligncenter size-full wp-image-890 noborder" /></div>
<p>So the first line is a point in space that is 1 unit along the X axis, the second line is a point at 1 unit along the Y axis, and similarly for the final line 1 unit along Z.</p>
<p>So now, if we want to figure out what a particular matrix looks like, just imagine doing the transform to the axis icon and see what happens.</p>
<h3>Scaling</h3>
<p>What would a 2x uniform scale do to the icon? It&#8217;d move each point to double it&#8217;s original position along each axis. Okay, well that&#8217;s easy to write:</p>
<div align="center">
<img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/10/ReadAMatrix_Scaling.gif" alt="ReadAMatrix_Scaling" title="ReadAMatrix_Scaling" width="162" height="85" class="aligncenter size-full wp-image-889 noborder" /></div>
<p>The video clip below shows what happens to the axis icon when we scale it uniformly by a factor of 2. I&#8217;ve annotated the end of each axis with it&#8217;s position. In the top left you can see the three point positions in order, shown to appear as a 3&#215;3 matrix.</p>
<p><object width="590" height="472"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8680784&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8680784&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="590" height="472"></embed></object><br /></p>
<h3>Rotation</h3>
<p>Starting with the identity matrix again, what would a 90 degree rotation around the Y axis give us? Well, that depends which way we rotate it. Looking down on the Y axis, an anti-clockwise rotation would move the X axis to point along the negative Z axis, and the Z axis to point along the positive X axis.</p>
<p>So for each point, just visualise where it ends up and write down its position.</p>
<div align="center"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/10/ReadAMatrix_RotateY.gif" alt="ReadAMatrix_RotateY" title="ReadAMatrix_RotateY" width="162" height="86" class="aligncenter size-full wp-image-888 noborder" /></div>
<p>Yep, it&#8217;s that simple. Check out the short clip below to see it in action.</p>
<p><object width="590" height="472"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8680859&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8680859&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="590" height="472"></embed></object><br /></p>
<p>If you happen to know a bit of scripting, you should be able to obtain the matrix of an object in your 3D scene and check for yourself that this really works.</p>
<h3>Reading the Matrix</h3>
<p>So why don&#8217;t we try to take a matrix and work backwards to see if we can figure out what it represents.</p>
<div align="center"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/10/ReadAMatrix_RotateX.gif" alt="ReadAMatrix_RotateX" title="ReadAMatrix_RotateX" width="127" height="77" class="aligncenter size-full wp-image-887 noborder" /></div>
<p>Compare the first line to the first line of the identity matrix at the top of this article. It&#8217;s exactly the same, so we know the X axis is unchanged. </p>
<p>Looking at the second row, the Y axis is reversed and now pointing down. The third row shows that the Z axis is reversed too. How would you do this in your 3D software if you were going to use the transform tools? </p>
<p>Actually, there are two ways. You could either negatively scale the Y and Z axes with the scale tool, as shown in the following clip:</p>
<p><object width="590" height="472"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8680888&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8680888&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="590" height="472"></embed></object><br /></p>
<p>Or you could rotate it around the X axis by 180 degrees, shown below:</p>
<p><object width="590" height="472"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8680829&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8680829&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="590" height="472"></embed></object><br /></p>
<p>So are we able to say which one? No, the matrix only tells us about the destination, not the journey.</p>
<div class="techdetail">
<h3>Technical Detail</h3>
<p>A word of warning, sometimes you&#8217;ll see matrices written in a different way. In this article, I have used the &#8220;row major&#8221; form where you can read the X, Y, and Z horizontally. Sometimes you&#8217;ll also see them written in &#8220;column major&#8221; format where you can read the axis vectors vertically instead. This can often lead to confusion when using the above technique.</p>
<p>If you research this further, it is usually stated (<a target="_blank" href="http://en.wikipedia.org/wiki/Row-major_order">Wikipedia</a>) that this difference in format only refers to the internal storage order of the numbers in computer memory, but I have come across situations where it has been written on the page in different ways too.
</div>
<h3>Using What You Know</h3>
<p>Here&#8217;s just one quick example of how you can use this knowledge:</p>
<p>Q. Imagine we have a scene with a boat bobbing around on a rough sea. How do we find out how upright this boat is? Another way of thinking about this is how aligned is the boat&#8217;s y-axis is with the world&#8217;s y-axis?</p>
<p>A. If we have the boat&#8217;s 3&#215;3 matrix, we know from the discussion above which row represents the y-axis of the boat (the middle row). With a bit of thought, we can figure out that if the boat is fully upright, this middle row of the matrix should read  [ 0 1 0 ]. Taking this further, we know that all we care about is the height of this point (who cares if it&#8217;s offset to the side in x or z right?), so really we&#8217;re only interested in the y coordinate of this point, i.e. the middle value.</p>
<p>This value gives us the perfect measure of how upright the boat is. A value of 1 indicates it is perfectly upright, and -1 means it is completely upside-down.</p>
<div align="center"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/10/ReadAMatrix_Upright.gif" alt="ReadAMatrix_Upright" title="ReadAMatrix_Upright" width="127" height="78" class="aligncenter size-full wp-image-897 noborder" /></div>
<h3>Going Further</h3>
<p>Now that you&#8217;re hopefully familiar with the basic anatomy of a 3&#215;3 matrix, the next step is to have a look at how it can be used to transform geometry. This isn&#8217;t a big leap; you&#8217;ve already seen visually how it works for the three points that lie on the axes.</p>
<p>After that, you&#8217;ll be more than ready to look at 4&#215;4 matrices which incorporate translation as well, but this is all material for future articles.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andynicholas.com/?feed=rss2&amp;p=861</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Retiming ICE caches</title>
		<link>http://www.andynicholas.com/?p=362</link>
		<comments>http://www.andynicholas.com/?p=362#comments</comments>
		<pubDate>Fri, 02 Oct 2009 14:38:29 +0000</pubDate>
		<dc:creator>AndyN</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[ICE]]></category>
		<category><![CDATA[XSI]]></category>

		<guid isPermaLink="false">http://www.andynicholas.com/?p=362</guid>
		<description><![CDATA[A complete guide to retiming particles in ICE.

The techniques discussed in this article were used for Sky Sports' "Super Sunday" television ident at The Mill,  earlier this year.]]></description>
			<content:encoded><![CDATA[<p>Occasionally a project comes along that has different frame rates in the edit. Sometimes it&#8217;s worse than that, certain shots can have the frame rate changing continuously; a technique that&#8217;s often called &#8220;speed ramping&#8221;. For example, imagine the real time to bullet time transition in The Matrix.</p>
<p>For the <a target="_blank" href="http://www.beam.tv/beamreel/jmRZQPvmVM">Sky Sports &#8220;Super Sunday&#8221; ident</a> we worked on this year (<a target="_blank" href="http://www.the-mill.com/index.php?A=967">Mill article</a>), almost every shot had some amount of speed ramping. Needless to say, this is usually where the FX TD has a minor heart attack in anticipation of the hell that he or she is about to go through. However, the flexibility of ICE in XSI now makes the process relatively easy, and this three page article will show you how to do it.</p>
<div align="center"><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/10/ScreenCapture05.jpg" class="lightview" rel="gallery[362]" title="ScreenCapture05"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/10/ScreenCapture05-300x168.jpg" alt="ScreenCapture05" title="ScreenCapture05" width="300" height="168" class="aligncenter size-medium wp-image-833" /></a></div>
<p><br/></p>
<h3>Why is speed ramping a problem?</h3>
<p>Physics engines in 3D applications tend to do their calculations on a per frame basis and they assume that the length of time that passes in each frame (known as the simulation step in ICE) isn&#8217;t changing. It&#8217;s an important optimisation as it simplifies the problem for them.</p>
<p>Numerical accuracy for collisions, and forces such as damping, are highly dependent on the simulation step. If the simulation step was allowed to change on each frame, it would introduce erratic behaviour into your object or particle motion.</p>
<p>Another problem you&#8217;d notice is that for different speed ramps, you would get different results from the simulation. Small inaccuracies in the way the simulation is calculated give rise to larger effects later on, despite starting with the exact same initial conditions. The key point to note is that larger simulation steps are more inaccurate than smaller ones, and changing the speed ramp means that you&#8217;d be introducing those inaccuracies in different places. This isn&#8217;t much good as you might have to redo your simulation if your speed ramp ever changes (which on our Sky job, it did on a number of occasions).</p>
<h3>Methods for dealing with speed ramping</h3>
<p>There are three ways to deal with speed ramping at the 3D stage:</p>
<ol>
<li>You add support for speed ramping into your physics engine. Actually, for particle simulations this isn&#8217;t as hard as it sounds. You just have to create your own &#8220;Simulate Particles&#8221; node. For rigid bodies&#8230; well&#8230; good luck! There&#8217;s a lot of maths involved, and it&#8217;s far from easy. Plus you&#8217;ll have to write your own collision system. (Yeah&#8230; no thanks!)
<ul>
<li>Pros:<br />
If you can get it to work, it&#8217;s a simple way of achieving the right result. You just run your simulation and you get the result.
</li>
<li>Cons:<br />
For anything other than particle simulations in ICE, it&#8217;s not particularly viable unless you&#8217;re good at physics programming. It would introduce inaccuracies. If your speed ramp needs to change later, you&#8217;ll have to re-simulate, and there&#8217;s no guarantee you&#8217;ll get the same results.
</li>
</ul>
</li>
<li>You simulate and cache the simulation at the same frame rate as you&#8217;re delivering the final sequence (in our case, 25 fps). At render time, if you need to go to slow motion, you&#8217;ll have to stretch out the simulation to slow it down. This means you&#8217;ll be trying to render at non-integer frame numbers and you&#8217;ll have to interpolate the particle positions and other attributes.
<ul>
<li>Pros:<br />
It&#8217;ll be fast and you won&#8217;t have much data to cache. You&#8217;re doing the minimum amount of work needed to get the result. If the speed ramp has to change, you don&#8217;t need to re-simulate since you&#8217;ve cached out all your data.
</li>
<li>Cons:<br />
It&#8217;s unlikely that this will look very nice if you have any collisions, as any sharp changes in velocity will look sluggish due to the interpolation. You might get away with it though, so it&#8217;s worth a try if you are up against a tight deadline.
</li>
</ul>
</li>
<li>You simulate and cache the simulation at the highest frame rate that you think you&#8217;ll need (in our case that was 100 fps). At render time, you&#8217;ll usually be replaying the cached simulation faster (e.g. when it&#8217;s running at 25 fps) by missing out the frames you don&#8217;t need. To guarantee smooth animation, you still need to interpolate between frames, as more often than not the dynamically changing frame rate will result in non-integer frame numbers.
<ul>
<li>Pros:<br />
Calculating at the highest frame rate means that your simulation will be super accurate. As with (2) if the speed ramp has to change, you don&#8217;t need to re-simulate since you&#8217;ve cached out all your data.
</li>
<li>Cons:<br />
You&#8217;ll be spending a lot of time simulating and have a lot of data to cache.
</li>
</ul>
</li>
</ol>
<h3>What we used on Sky</h3>
<p>The third option is nearly always the best way to go. It&#8217;s a good solution, providing you&#8217;ve got plenty of disc space, and have enough time to do the simulations. </p>
<p>For Sky, we animated and simulated everything at 100 fps and cached all that data to disk. (If an analogy helps, just think of it as filming live action with a high speed camera). </p>
<div align="center"><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/10/ScreenCapture01.jpg" class="lightview" rel="gallery[362]" title="ScreenCapture01"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/10/ScreenCapture01-300x168.jpg" alt="ScreenCapture01" title="ScreenCapture01" width="300" height="168" class="aligncenter size-medium wp-image-835" /></a></div>
<p><br/></p>
<p>For each shot, we had a curve that represented the current frame to load from the disk cache. This curve was an incredibly important asset in our pipeline as it was used to synchronise multiple packages (XSI, Houdini, Maya, Massive, Cinema 4D) to render everything at precisely the same moment in time. </p>
<p>Note that since the speed ramps gave smooth changes in frame rate, the frame numbers given by the retime curve weren&#8217;t usually integral values (e.g. 1, 2, 3, 4, etc.), but were fractional (1.4, 2.8, 4.2, 5.6, etc.). This meant that camera and object transforms, meshes, and particle attributes had to be interpolated to be properly evaluated at these fractional frame values. More on that later.</p>
<p>There&#8217;s one last issue you need to take into account when doing any sort of retiming of a cache. You can read about that on the <a href="http://www.andynicholas.com/?p=362&#038;page=2">next page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andynicholas.com/?feed=rss2&amp;p=362</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Storm Over Frankfurt</title>
		<link>http://www.andynicholas.com/?p=811</link>
		<comments>http://www.andynicholas.com/?p=811#comments</comments>
		<pubDate>Sun, 27 Sep 2009 21:31:10 +0000</pubDate>
		<dc:creator>AndyN</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Video]]></category>
		<category><![CDATA[Frankfurt]]></category>
		<category><![CDATA[Germany]]></category>
		<category><![CDATA[lightning]]></category>
		<category><![CDATA[storm]]></category>
		<category><![CDATA[viral]]></category>
		<category><![CDATA[youtube]]></category>

		<guid isPermaLink="false">http://www.andynicholas.com/?p=811</guid>
		<description><![CDATA[Back in August, The Mill gave me a new challenge. There was a new job coming in to create a viral for Audi and they wanted me to lead and act as VFX supervisor on the shoot.]]></description>
			<content:encoded><![CDATA[<p>Back in August, The Mill gave me a new challenge. There was a new job coming in to create a viral for Audi and they wanted me to lead and act as VFX supervisor on the shoot. To be fair, I&#8217;d been pestering them to let me do this for ages, so it was great to be given the chance.</p>
<p>The brief was pretty simple. We had to create a lightning storm over Frankfurt and show a direct strike on a bridge over the river. We were told to &#8220;Just make it look awesome!&#8221;. Sure, we can do that!</p>
<p>I&#8217;ll write a post soon on how we made it. But for now, here&#8217;s the finished piece, as published on YouTube:</p>
<div class="embeddedvideoleft"><object width="590" height="442"><param name="movie" value="http://www.youtube.com/v/H_SKemnGujQ&#038;fs=1" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><embed src="http://www.youtube.com/v/H_SKemnGujQ&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="590" height="442"></embed></object></div>
<p><br/>So it turns out that one of the best things about doing a viral is that you get to see some feedback from the public in the comments they leave on YouTube. Most people spotted it as a fake, and I really don&#8217;t mind as they were quite complimentary on the whole. If we&#8217;d kept it totally within the bounds of reality the piece wouldn&#8217;t have been so effective. The point of the viral was to make sure that it got everyone&#8217;s attention. </p>
<p>Other people totally bought it. </p>
<blockquote><p>&#8220;Your all f******s. Why would someone fake something like this? What&#8217;s the point? Wow I faked a lightning﻿ storm for 100,000 views? This is most likely real. But the dudes who shot this are idiots for being in the water during s lightning storm&#8221;</p></blockquote>
<p>One guy thought it was fake and started making assertions such as:</p>
<blockquote><p>&#8220;actually, if you look closely, you can see they are not in the water &#8211; they are driving﻿ on a road at the riverside!&#8221;.
</p></blockquote>
<p>Nope, we were definitely in a boat! I think it&#8217;s amazing what people convince themselves they&#8217;re seeing.</p>
<p>This made me laugh too:</p>
<blockquote><p>&#8220;Oh my god, is this REAL?</p>
<p>And can Audi protect﻿ me from lightning? </p>
<p>PLEASE HELP!&#8221;
</p></blockquote>
<p>Finally, this one&#8217;s probably my favourite (which only makes sense if you&#8217;ve seen <a target="_blank"  href="http://www.imdb.com/title/tt0100802/">Total Recall</a>):</p>
<blockquote><p>&#8220;haha, is the governator on that boat? are they on their way to ze mines to turn on the reactor&#8230;.damit﻿ cohagen you know the reactor makes air, why don&#8217;t you just turn it on? Quaid&#8230;.Quaid&#8230;.&#8217;start the reactor&#8217; &#8220;</p></blockquote>
<p>Overall the campaign was a success. At the time of writing this, the spot has had well over 288,000 hits, the vast majority of which happened in the first week of it being posted. There was a lot of <a target="_blank" href="http://www.google.com/search?q=electricity+untamed">press coverage</a> too, particularly in the automotive press as you&#8217;d expect. It was all to publicise Audi&#8217;s new e-tron concept car. The e-tron has one battery, four electric motors, and an insane amount of torque which means it can go from standing to 62 mph in 4.8 seconds. </p>
<p>Here&#8217;s the link to Audi&#8217;s viral campaign website <a target="_blank" href="http://www.electricityuntamed.com">www.electricityuntamed.com</a> where you can see a video of the launch, or you can go <a target="_blank" href="http://www.autoblog.com/2009/09/15/officially-official-frankfurt-2009-audi-e-tron-4-motors-1-b/">here</a> to view a short article and Audi&#8217;s official press release about the e-tron.</p>
<p>You can read The Mill&#8217;s article on the job <a target="_blank" href="http://www.the-mill.com/index.php?A=980">here</a>.</p>
<div align="center">
<hr width="200"/></div>
<p><br/></p>
<p>In addition to &#8220;Storm Over Frankfurt&#8221;, two other virals were shot. Minimal post production was needed by The Mill except for some rig removal work. They&#8217;re great spots and very funny, so I&#8217;ve embedded them below for your convenience. Enjoy!</p>
<div class="embeddedvideoleft"><object width="590" height="442"><param name="movie" value="http://www.youtube.com/v/5Jj8_87VDHc&#038;fs=1" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><embed src="http://www.youtube.com/v/5Jj8_87VDHc&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="590" height="442"></embed></object></div>
<p><br/></p>
<div class="embeddedvideoleft"><object width="590" height="442"><param name="movie" value="http://www.youtube.com/v/tJ7tqVXa-PQ&#038;fs=1" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><embed src="http://www.youtube.com/v/tJ7tqVXa-PQ&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="590" height="442"></embed></object></div>
<p><br/></p>
]]></content:encoded>
			<wfw:commentRss>http://www.andynicholas.com/?feed=rss2&amp;p=811</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pyrotechnics: Blowing Up a Car</title>
		<link>http://www.andynicholas.com/?p=714</link>
		<comments>http://www.andynicholas.com/?p=714#comments</comments>
		<pubDate>Tue, 08 Sep 2009 14:04:38 +0000</pubDate>
		<dc:creator>AndyN</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[NFTS]]></category>
		<category><![CDATA[Pyrotechnics]]></category>
		<category><![CDATA[explosion]]></category>
		<category><![CDATA[fire]]></category>
		<category><![CDATA[Graham Brown]]></category>
		<category><![CDATA[health and safety]]></category>

		<guid isPermaLink="false">http://www.andynicholas.com/?p=714</guid>
		<description><![CDATA[Blowing cars up with a rocket launcher? Of course. It's just another day on the SFX/VFX course at the NFTS.

Find out how we did it for real.]]></description>
			<content:encoded><![CDATA[<div class="retrospective">
<em>This post is one of a series of entries that will be talking about some of the things I did while at the NFTS (2006-7).<br />
</em></div>
<h3>Back to School</h3>
<p>There&#8217;s no doubt that leaving my job at Lionhead Studios to go to film school for a year was a risky move for me to take. It was a tactical decision to try and rebrand my career towards film and commercials work; something that I&#8217;d been trying to do for a while. </p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FireFront.jpg" class="lightview" rel="gallery[714]" title="CarBang_FireFront"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FireFront-300x200.jpg" alt="CarBang_FireFront" title="CarBang_FireFront" width="300" height="200" class="alignleft size-medium wp-image-770" /></a></p>
<p>One of the other reasons that I decided to sign up for the VFX/SFX course run by the <a href="http://www.nfts.co.uk">NFTS</a> was because of the pyrotechnics module that they offered. Having grown up watching films like <em>Raiders of the Lost Ark</em> and being utterly consumed with fascination about the stunts and effects, I felt that this was my opportunity to satisfy that craving.</p>
<p>I wasn&#8217;t disappointed. Not even close.</p>
<h3>The Setup</h3>
<p>There were six of us on the course: Kate, Kia, Mattias, Nick, Seru, and myself. We were all from a wide range of backgrounds which made for an great mix of skills and experience. The first month on the course was spent learning about fire, explosives, rain, snow, firearms, and many other areas that an SFX technician has to have a good understanding of. The car explosion stunt was the climax to the course module.</p>
<p>I&#8217;m not sure where the idea came from, but I think I suggested that it would be a cool idea to blow up the car with a rocket launcher. I figured that blowing up a car without a good explanation would be a bit dull. Far better to make it look like we were hitting it with an RPG. Michael Bay eat your heart out!</p>
<p>One thing we all learnt in that first month as trainee SFX technicians: in a low budget scenario, you literally need to beg, steal, or borrow whatever you need to get the job done. Resourcefulness can make the difference between getting the shot, or not.</p>
<p>The begged items came from Graham Brown in the form of fishing wire and some fireworks. Although to be honest, I didn&#8217;t need to do too much begging. Graham as usual was more than happy to help out.</p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_RocketLauncher.jpg" class="lightview" rel="gallery[714]" title="CarBang_RocketLauncher"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_RocketLauncher-150x150.jpg" alt="CarBang_RocketLauncher" title="CarBang_RocketLauncher" width="150" height="150" class="alignleft size-thumbnail wp-image-775" /></a></p>
<p>In true <a href="http://en.wikipedia.org/wiki/Blue_Peter">Blue Peter</a> style, the rocket launcher was made from a cardboard tube; this time, stolen from our communal TV room at the film school (it was in a pile of rubbish and no one was using it). I painted it green, and fixed a wall bracket to it as a makeshift sight. A bit of yellow and black tape finished it off.</p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_SteeringWheel.jpg" class="lightview" rel="gallery[714]" title="CarBang_SteeringWheel"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_SteeringWheel-150x150.jpg" alt="CarBang_SteeringWheel" title="CarBang_SteeringWheel" width="150" height="150" class="alignright size-thumbnail wp-image-777" /></a></p>
<p>To make handbrake turns easier, I rigged the steering wheel with a cylindrical door handle borrowed from a door found on the NFTS main stage. I should point out that it wasn&#8217;t from a real door, just one that was lying around previously used as part of a set on an earlier production. Before we blew the car up, I got it back and reattached it to the door the next day.</p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_ArriCameras.jpg" class="lightview" rel="gallery[714]" title="CarBang_ArriCameras"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_ArriCameras-150x150.jpg" alt="CarBang_ArriCameras" title="CarBang_ArriCameras" width="150" height="150" class="alignleft size-thumbnail wp-image-755" /></a></p>
<p>One thing I didn&#8217;t mention in the guerrilla SFX &#8220;beg, steal, or borrow&#8221; toolkit was bribing. The NFTS course managers persuaded Arri to come along with some of their high speed cameras. Not through any monetary bribing (this was low budget, don&#8217;t forget), but as a promise of some great stock footage for any of their product demos. In the end, they brought two cameras which, despite the poor light conditions, were run at 200 fps and 400 fps.<br clear="all"/></p>
<h3>The Car</h3>
<p>We didn&#8217;t have any sort of story line or plot as we were more interested in the SFX, but we still wanted to shoot some footage with the car. If we&#8217;d had two cars it would have been better, but again, our budget didn&#8217;t stretch that far. So we kept it simple and just used the deserted market stalls as a background for some interesting shots. </p>
<p>You might be surprised how tricky it is to do a handbrake turn in a Ford Escort, even in the wet. It took a bit of practice but I got there in the end. The door handle on the steering wheel helped, but I found the key was to initiate the turn, slam on the brakes to throw the weight forward, and then yank on the handbrake to throw the rear end round. The one that you see in the video nearly went 180º.</p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_EmptyRear.jpg" class="lightview" rel="gallery[714]" title="CarBang_EmptyRear"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_EmptyRear-150x150.jpg" alt="CarBang_EmptyRear" title="CarBang_EmptyRear" width="150" height="150" class="alignleft size-thumbnail wp-image-758" /></a></p>
<p>After we&#8217;d done the other shots with the car, we did a final run ending up with the handbrake turn. With the car in the final position, we set about stripping it down to remove any dangerous or unnecessary parts. High on this list was the petrol tank which was drained and removed. We were also told that the pistons for the hatchback boot can be highly dangerous in a fire and can explode violently. Apparently the fire services are quite nervous about these things going off in motorway fires!</p>
<p>Other things that were done: the car battery was removed, tyres were let down, brake fluids and oil were drained, and many other parts were removed. All this was to make sure that we didn&#8217;t have any unpredictable results that could be a safety hazard, and also because we didn&#8217;t want the car to burn for hours after the explosion.</p>
<p>In case you&#8217;re wondering, the car had been bought for about £300 specifically for us to blow it up. Coincidentally, it bore more than a striking resemblance to my own car at the time so I swapped the wheel hubcaps as they were better than mine!</p>
<h3>Rigging the Explosives</h3>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Bonnet.jpg" class="lightview" rel="gallery[714]" title="CarBang_Bonnet"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Bonnet-150x150.jpg" alt="CarBang_Bonnet" title="CarBang_Bonnet" width="150" height="150" class="alignleft size-thumbnail wp-image-756" /></a>After the car had been stripped down, we set up the charges. Unfortunately, there&#8217;s a limited amount of detail that I can go into without being a bit irresponsible by telling everyone how to blow stuff up, but suffice to say, we used several standard petrol based mortars along with a couple of charges to blow the windscreen.</p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Boot.jpg" class="lightview" rel="gallery[714]" title="CarBang_Boot"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Boot-150x150.jpg" alt="CarBang_Boot" title="CarBang_Boot" width="150" height="150" class="alignright size-thumbnail wp-image-757" /></a> All the charges had to be wired up with long lengths of electrical wire so that we could be at least 50m away when it went off. The charges were connected to a custom made detonation box belonging to Graham. </p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FishingWire.jpg" class="lightview" rel="gallery[714]" title="CarBang_FishingWire"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FishingWire-150x150.jpg" alt="CarBang_FishingWire" title="CarBang_FishingWire" width="150" height="150" class="alignleft size-thumbnail wp-image-780" /></a></p>
<p>The rocket launcher (err&#8230; cardboard tube) was connected to the front of the car by the fishing wire. We sellotaped a firework rocket to a drinking straw that had the fishing wire threaded through it.</p>
<p>During the set up, we were all aware that it was a race against time. Being November we had a limited amount of daylight, and it was made worse by thick cloud cover and drizzling rain. Trying to film something as bright as a fiery explosion isn&#8217;t something you want to do in complete darkness, especially with high speed cameras. You&#8217;d see either the explosion or the surroundings, not both; at least not in any detail.</p>
<h3>Bang!!</h3>
<p>So when the time came to set everything off, we were knackered. Making sure that all the cameras were up to speed, we gave a countdown and lit the firework. It shot along the fishing line, hit the car, which blew up in a series of explosions, one of which sent the windscreen 30 feet into the air. Everything worked perfectly and at the right time; something that we were all surprised by considering the pressure we had been under and the weather conditions.</p>
<div align="center">
<a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Explosion01.jpg" class="lightview" rel="gallery[714]" title="CarBang_Explosion01"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Explosion01-150x150.jpg" alt="CarBang_Explosion01" title="CarBang_Explosion01" width="150" height="150" class="alignnone size-thumbnail wp-image-759" /></a><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Explosion02.jpg" class="lightview" rel="gallery[714]" title="CarBang_Explosion02"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Explosion02-150x150.jpg" alt="CarBang_Explosion02" title="CarBang_Explosion02" width="150" height="150" class="alignnone size-thumbnail wp-image-760" /></a><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Explosion03.jpg" class="lightview" rel="gallery[714]" title="CarBang_Explosion03"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Explosion03-150x150.jpg" alt="CarBang_Explosion03" title="CarBang_Explosion03" width="150" height="150" class="alignnone size-thumbnail wp-image-761" /></a></p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Explosion04.jpg" class="lightview" rel="gallery[714]" title="CarBang_Explosion04"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Explosion04-150x150.jpg" alt="CarBang_Explosion04" title="CarBang_Explosion04" width="150" height="150" class="alignnone size-thumbnail wp-image-762" /></a><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Explosion05.jpg" class="lightview" rel="gallery[714]" title="CarBang_Explosion05"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Explosion05-150x150.jpg" alt="CarBang_Explosion05" title="CarBang_Explosion05" width="150" height="150" class="alignnone size-thumbnail wp-image-763" /></a><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Explosion06.jpg" class="lightview" rel="gallery[714]" title="CarBang_Explosion06"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_Explosion06-150x150.jpg" alt="CarBang_Explosion06" title="CarBang_Explosion06" width="150" height="150" class="alignnone size-thumbnail wp-image-764" /></a>
</div>
<p>We had spent a lot of time carefully laying out and labelling the numerous cables that were used to set off the explosions. Since we had limited resources, many of the cables were made up of two smaller ones, so we had to make sure that all connections were working. I think we checked everything at least twice. Graham&#8217;s firing box had a special mode for testing connections by sending a low powered current down the cable and through the charge. It wouldn&#8217;t be enough to detonate the explosive, but enough to be able to check the continuity of the circuit. We would still treat it as a live firing though&#8230; just in case.</p>
<h3>Safety First</h3>
<p>There are lots of precautions one takes when working with explosives. While I said that I wouldn&#8217;t go into any details on how to make something go bang, I think it&#8217;s safe enough to discuss some of the safety measures we took. </p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FireFront.jpg" class="lightview" rel="gallery[714]" title="CarBang_FireFront"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FireFront-150x150.jpg" alt="CarBang_FireFront" title="CarBang_FireFront" width="150" height="150" class="alignleft size-thumbnail wp-image-770" /></a></p>
<p>You have to be very aware of what everyone is doing, especially when you are connecting the charges to the lines. For example, it&#8217;s all too easy to leave the battery connected to the firing box with the key in the on position. While that wouldn&#8217;t detonate the charge (you&#8217;d still need to press the right button), it&#8217;s not a situation you want to be in. The standard Health and Safety strategy is that it&#8217;s everyone&#8217;s responsibility to look out for each other, and to make sure that these slip ups don&#8217;t happen. It&#8217;s all about minimising risk.</p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FireBack.jpg" class="lightview" rel="gallery[714]" title="CarBang_FireBack"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FireBack-150x150.jpg" alt="CarBang_FireBack" title="CarBang_FireBack" width="150" height="150" class="alignright size-thumbnail wp-image-767" /></a></p>
<p>Generally you don&#8217;t want to be wearing anything that has a tendency to create static electricity. It is possible (although unlikely) that static can generate enough power to set off a charge. Synthetic materials are well known for being good sources, so they should be avoided.</p>
<p>This one&#8217;s important (and you&#8217;ll recognise this if you&#8217;ve ever bought fireworks). Never return to a charge if it doesn&#8217;t go off. There&#8217;s a procedure to follow in this situation. Generally the safest thing to do with a dud is to place another charge next to it, and detonate one using the other. We were shown a video of what can happen if you try to take shortcuts. I believe the poor chap lost hearing in one ear and part of a finger.</p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FireCam.jpg" class="lightview" rel="gallery[714]" title="CarBang_FireCam"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FireCam-150x150.jpg" alt="CarBang_FireCam" title="CarBang_FireCam" width="150" height="150" class="alignleft size-thumbnail wp-image-768" /></a></p>
<p>The best way to make sure a charge is safe is to twist the two connections together. It makes sure that there&#8217;s no potential difference between the wires so it&#8217;s impossible for the charge to be set off by a voltage. Most pyro charges are supplied in this configuration. Of course, there&#8217;s no guarantee that you won&#8217;t set them off with excessive or prolonged exposure to heat or some type of chemical agent, so you still need to take care.<br clear="all"/></p>
<h3>Other Considerations</h3>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FireServices.jpg" class="lightview" rel="gallery[714]" title="CarBang_FireServices"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FireServices-150x150.jpg" alt="CarBang_FireServices" title="CarBang_FireServices" width="150" height="150" class="alignleft size-thumbnail wp-image-771" /></a>Whenever you do any sort of pyrotechnics work, it&#8217;s nearly always a good idea to let the local emergency services know in advance. With an explosion as large as the one we did, it would be pretty likely that someone would call the fire brigade &#8211; which they did. About ten minutes after we ignited our Ford Escort bonfire the fire services turned up, blue lights flashing. </p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FireExtinguish.jpg" class="lightview" rel="gallery[714]" title="CarBang_FireExtinguish"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_FireExtinguish-150x150.jpg" alt="CarBang_FireExtinguish" title="CarBang_FireExtinguish" width="150" height="150" class="alignright size-thumbnail wp-image-769" /></a></p>
<p>If we hadn&#8217;t spoken to them first, they would have charged us a call out fee. They were a great bunch of guys though, and were probably happy for the break in their routine. The NFTS also did a leaflet drop in the area a few days before so that local residents wouldn&#8217;t be alarmed.</p>
<p><a href="http://homepage.ntlworld.com/grahambrown.sfx/index.html">Graham Brown</a> was our pyrotechnics tutor and supervisor. He worked for many years at the BBC providing special effects work for a huge number of different shows. When he&#8217;s not tutoring at the school, he still does work on a freelance basis for shows like <a href="http://en.wikipedia.org/wiki/Waking_the_Dead_(TV_series)">Waking The Dead</a> (which I was lucky enough to assist him with on three occasions &#8211; more in a future post). I&#8217;d like to take this opportunity to thank him for all his enthusiasm, dedication, and hard work, and for such an amazing experience that I&#8217;ll never forget.</p>
<p>Thanks should also go to John Rowe and Sarah Hayward, the course directors, who worked tirelessly to make sure our time at the school was chock filled with fun things like this to do. And finally a big shout out to the other guys on the course &#8211; those were good times eh!</p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_TheTeam.jpg" class="lightview" rel="gallery[714]" title="CarBang_TheTeam"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/09/CarBang_TheTeam-300x200.jpg" alt="CarBang_TheTeam" title="CarBang_TheTeam" width="300" height="200" class="alignleft size-medium wp-image-778" /></a><br />
Rear, left to right:<br/>John Seru, Kate Walshe, Mattias Engstrom,<br/> Nick Preston, Kia Coates, Andy Nicholas.</p>
<p>Front:<br/>Graham Brown</p>
<p>(And then we had to clear up the mess)</p>
<p><br clear="all"/></p>
<h3>The Video</h3>
<p>Here&#8217;s the final cut with a wee bit of compositing to make it look like the car was still moving when we blew it up.</p>
<p><object width="590" height="442"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=5400512&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=5400512&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="590" height="442"></embed></object><br /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.andynicholas.com/?feed=rss2&amp;p=714</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Houdini: Multiparms</title>
		<link>http://www.andynicholas.com/?p=639</link>
		<comments>http://www.andynicholas.com/?p=639#comments</comments>
		<pubDate>Tue, 25 Aug 2009 22:55:23 +0000</pubDate>
		<dc:creator>AndyN</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Houdini]]></category>
		<category><![CDATA[expressions]]></category>
		<category><![CDATA[multiparm]]></category>
		<category><![CDATA[SOPs]]></category>

		<guid isPermaLink="false">http://www.andynicholas.com/?p=639</guid>
		<description><![CDATA[If you've ever wondered how to use multiparms in your own assets and tools, then this four page tutorial will show you how.

It also covers how to link expressions to them, and a couple of other tricks too. ]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve never heard of multiparms; here are a couple of examples I&#8217;m sure you will know:</p>
<p><center><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/08/AddSOP.jpg" class="lightview" rel="gallery[639]" title="AddSOP"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/08/AddSOP-150x150.jpg" alt="AddSOP" title="AddSOP" width="150" height="150" class="size-thumbnail wp-image-697" /></a><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/08/ObjectMergeSOP.jpg" class="lightview" rel="gallery[639]" title="ObjectMergeSOP"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/08/ObjectMergeSOP-150x150.jpg" alt="ObjectMergeSOP" title="ObjectMergeSOP" width="150" height="150" class="size-thumbnail wp-image-699" /></a></center></p>
<p>The Add SOP on the left uses a multiparm to get a list of point positions from the user, while the Object Merge SOP shown on the right uses a multiparm to merge geometry from multiple sources at once.</p>
<p>This simple tutorial will show you how to use multiparms in expressions and your own tools.</p>
<h3>Introduction</h3>
<p>Multiparms are Houdini&#8217;s way of getting a list of items from the user. They comprise of a single parameter that stores the number of entries in the list, and a list of parameters numbered sequentially that make up those entries.</p>
<p><center><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/08/multiparmexplained.jpg" alt="multiparmexplained" title="multiparmexplained" width="479" height="243" class="aligncenter size-full wp-image-698" /></center></p>
<p>Something which is particularly useful is that each entry doesn&#8217;t have to be made up of just one parameter. Houdini lets you store multiple parameters in each entry. In effect, you can think of each one being like a record in a database. Each one can contain a number of fields in which you can store information.</p>
<p>In this tutorial, I&#8217;ll only be looking at a multiparm that contains single parameter entries.</p>
<h3>Initial Setup</h3>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/08/multiparm_1.jpg" class="lightview" rel="gallery[639]" title="Step 1"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/08/multiparm_1-300x179.jpg" alt="Step 1" title="Step 1" width="300" height="179" class="alignleft size-medium wp-image-663" /></a>To start, make a Geometry object, call it &#8220;geo_boxes&#8221;, and press <em>Enter</em> to jump inside.<br />
<br clear="all"></p>
<p><a href="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/08/multiparm_2.jpg" class="lightview" rel="gallery[639]" title="Step 2"><img src="http://www.andynicholas.com/apnwp/wp-content/uploads/2009/08/multiparm_2-300x179.jpg" alt="Step 2" title="Step 2" width="300" height="179" class="alignleft size-medium wp-image-664" /></a>Inside, create a Box SOP, and a Copy Sop with their default parameters, and connect them as shown. </p>
<p>Sticking to the Houdini convention that most people use; add a Null Sop called &#8220;OUT&#8221; and set its display flag.<br />
<br clear="all"></p>
<p>On the next page, we&#8217;ll create the multiparm.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andynicholas.com/?feed=rss2&amp;p=639</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
