<?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>Softimage Blog &#187; JScript</title>
	<atom:link href="http://www.softimageblog.com/archives/category/scripting/jscript/feed" rel="self" type="application/rss+xml" />
	<link>http://www.softimageblog.com</link>
	<description>People and thoughts behind Softimage in production...</description>
	<lastBuildDate>Mon, 21 Jun 2010 20:40:48 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Two Undocumented Lip sync commands in Softimage 2011 SP1</title>
		<link>http://www.softimageblog.com/archives/517#utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=two-undocumented-lip-sync-commands-in-softimage-2011-sp1</link>
		<comments>http://www.softimageblog.com/archives/517#comments</comments>
		<pubDate>Mon, 21 Jun 2010 20:40:48 +0000</pubDate>
		<dc:creator>Luc-Eric</dc:creator>
				<category><![CDATA[Animation]]></category>
		<category><![CDATA[JScript]]></category>

		<guid isPermaLink="false">http://www.softimageblog.com/?p=517</guid>
		<description><![CDATA[In 2011 SP1, there are three new commands to get Face Robot lip sync data out into your own tools.  One of them doesn't even require the use of Face Robot and calls the speech recognition library directly]]></description>
			<content:encoded><![CDATA[<p>Hi there! It&#8217;s been a while..</p>
<p>In Softimage 2010, a new lip sync feature was added to Face Robot (here&#8217;s the <a href="http://softimage.wiki.softimage.com/xsidocs/dp888102.htm">doc</a>).  In 2011 SP1, there are three new commands to get the data out into your own tools.  One of them doesn&#8217;t even require the use of Face Robot and  calls the speech recognition library directly.</p>
<p>The commands return VBScript-compatible multi-dimensional arrays.    This is transparent in VBScript and Python, but it requires a bit of magic in JScript, so check the example in the first command if that&#8217;s what you&#8217;re using.</p>
<h2><strong>Getting Phonemes without Face Robot</strong></h2>
<h2>SIExtractPhonemes</h2>
<h3>Description</h3>
<div>
Extracts phonemes from an audio file using a text to guide the recognition</p>
</div>
<h3>Scripting Syntax</h3>
<div>
<table>
<tbody>
<tr>
<td>
<pre>oReturn = SIExtractPhonemes( Language, FileName, GuideText );</pre>
</td>
</tr>
</tbody>
</table>
</div>
<h3>Return Value</h3>
<div>
<p>Returns a multi-dimentional array of results. Each column will contain</p>
<p>1) The Unicode IPA code of the phoneme</p>
<p>2) The Start Time of the  phoneme, in seconds</p>
<p>3) The End Time of the phoneme, in seconds</p>
<p>4)  A human-readable hint of phoneme, useful for debugging</p>
</div>
<h3>Parameters</h3>
<div>
<table cellspacing="5" cellpadding="5">
<tbody>
<tr>
<th>Parameter</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>Language</td>
<td><a href="http://softimage.wiki.softimage.com/sdkdocs/String.htm">String</a></td>
<td>Language to use. &#8220;en&#8221; for English, or &#8220;jp&#8221; for Japanese</td>
</tr>
<tr>
<td>FileName</td>
<td><a href="http://softimage.wiki.softimage.com/sdkdocs/String.htm">String</a></td>
<td>Path to an audio file, for example a .wav or an .avi file. Mono and 16000k  is recommend. Same audio formats as Audio in Softimage; MP3 not supported.</td>
</tr>
<tr>
<td>GuideText</td>
<td><a href="http://softimage.wiki.softimage.com/sdkdocs/String.htm">String</a></td>
<td>Text that match the spoken words in the audio file. Avoid any unusual  punctuations or strange characters that may throw off the engine</td>
</tr>
</tbody>
</table>
</div>
<h3>Examples</h3>
<div>
<h4>JScript Example</h4>
<div>
<table>
<tbody>
<tr>
<td>
<pre>//returns a VBArray object, which require using the .getItem method in Jscript because they are not
//native objects there.
//However, they work transparently like multi-dimentionnal arrays in VBscript and Python
var res = SIExtractPhonemes ("en", "s:\\here_be_dragons.wav", "Here be dragons, the map says");
arraysize = res.ubound( 1 );
logmessage( arraysize + "phonemes found" );
for (  i=0; i &lt; arraysize; i++)
{
logmessage( "IPA#" + res.getItem(i,0)
         + "(" + res.getItem(i,3) + ") "
         + "Start Time(sec) " + res.getItem(i,1)
         + "End Time(sec) " + res.getItem(i,2) );
}</pre>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p><strong><br />
</strong></p>
<h2><strong>Getting Lip Sync Stuff Out of Face Robot</strong></h2>
<p>This allows the artists to tweak the phonemes with the Face Robot UI, but used the data outside of Face Robot, perhaps in a game engine that does phoneme blending already.</p>
<p>The second command even allows you to get the result of the blend algorithm of Face Robot, so you can make a simplified playback environment.</p>
<h2>GetPhonemeFromSpeechClip</h2>
<h3>Description</h3>
<div>
<p>Returns the data of the Face Robot speech operator, as shown on the tracks of  in the Lip Sync view. The data starts at time zero, and needs to be offsetted by  the offset of the Speech Clip.</p>
</div>
<h3>Scripting Syntax</h3>
<div>
<table>
<tbody>
<tr>
<td>
<pre>oReturn = GetPhonemeFromSpeechClip( SpeechClip );</pre>
</td>
</tr>
</tbody>
</table>
</div>
<h3>Return Value</h3>
<div>
<p>Returns a multi-dimentional array of results. Each column will contain</p>
<p>1) The Unicode IPA code of the phoneme</p>
<p>2) The Start Time of the  phoneme, in seconds</p>
<p>3) The End Time of the phoneme, in seconds</p>
<p>4)  A human-readable hint of phoneme, useful for debugging</p>
<p>5) weight for this  phoneme</p>
<p>6) in falloff for this phoneme</p>
<p>7) out falloff for this  phoneme</p>
<p>8) shape weight for this phoneme</p>
<p>9) shape in falloff for  this phoneme</p>
<p>10) shape out falloff for this phoneme</p>
<p>11) blend  start scale factor</p>
<p>12) blend end scale factor</p>
<p>13) phoneme  variation</p>
</div>
<h3>Parameters</h3>
<div>
<table cellspacing="5" cellpadding="5">
<tbody>
<tr>
<th>Parameter</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>SpeechClip</td>
<td><a href="http://softimage.wiki.softimage.com/sdkdocs/String.htm">String</a></td>
<td>The Speech Clip from the animation mixer</td>
</tr>
</tbody>
</table>
</div>
<h3>Examples</h3>
<div>
<h4>VBScript Example</h4>
<div>
<table>
<tbody>
<tr>
<td>
<pre>phonemes = GetPhonemesFromSpeechClip ("Face.Mixer.Phoneme_Speech.SpeechAction_Clip")
LogMessage "phoneme data"
for i = 0 to UBound( phonemes )
	LogMessage "IPA # " &amp; phonemes(i, 0) &amp; "(" &amp; phonemes(i, 3) &amp; ")" &amp; " Start (sec)" &amp; phonemes(i, 1) &amp; " End (sec)" &amp; phonemes(i, 2)
next
</pre>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h2>GetPhonemeBlendFromSpeechClip</h2>
<h3>Description</h3>
<div>
<p>Queries the Face Robot speech operator for the list of phonemes and weights  at a given time, as evaluated by its blend algorithm. At a given time there  generally is the current phoneme, as shown in the lipsync view, but also some of  the previous and the next one. With its different parameters, the speech  operator could evaluate a different blend for the lips, jaw and tongue.</p>
</div>
<h3>Scripting Syntax</h3>
<div>
<table>
<tbody>
<tr>
<td>
<pre>oReturn = GetPhonemeBlendFromSpeechClip( SpeechClip, [Channel], [Time] );</pre>
</td>
</tr>
</tbody>
</table>
</div>
<h3>Return Value</h3>
<div>
<p>Returns a multi-dimentional array of results. Each column will contain</p>
<p>1) The Unicode IPA code of the phoneme. Value zero is the rest pose</p>
<p>2) A human-readable hint of phoneme, useful for debugging</p>
<p>3) The  weight of the viseme at this time</p>
<p>4) The viseme variation selected by the  user</p>
</div>
<h3>Parameters</h3>
<div>
<table cellspacing="5" cellpadding="5">
<tbody>
<tr>
<th>Parameter</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>SpeechClip</td>
<td><a href="http://softimage.wiki.softimage.com/sdkdocs/String.htm">String</a></td>
<td>The Speech Clip from the animation mixer</td>
</tr>
<tr>
<td>Channel</td>
<td><a href="http://softimage.wiki.softimage.com/sdkdocs/Integer.htm">Integer</a></td>
<td>0 for Lips, 1 for Jaw, 2 for TongueDefault Value: 1</td>
</tr>
<tr>
<td>Time</td>
<td><a href="http://softimage.wiki.softimage.com/sdkdocs/Integer.htm">Integer</a></td>
<td>Frame at which to evaluate the blendDefault Value: Current frame.</td>
</tr>
</tbody>
</table>
</div>
<h3>Examples</h3>
<div>
<h4>VBScript Example</h4>
<div>
<table>
<tbody>
<tr>
<td>
<pre>phonemes = GetPhonemeBlendFromSpeechClip ("Face.Mixer.Phoneme_Speech.SpeechAction_Clip")
LogMessage "phoneme blend"
for i = 0 to UBound( phonemes )
	LogMessage "IPA # " &amp; phonemes(i, 0) &amp; "(" &amp; phonemes(i, 1) &amp; ")" &amp; " Weight " &amp; phonemes(i, 2 )
next</pre>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<img src="http://www.softimageblog.com/?ak_action=api_record_view&id=517&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.softimageblog.com/archives/517/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Object oriented programming, once again.</title>
		<link>http://www.softimageblog.com/archives/260#utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=object-oriented-programming-once-again</link>
		<comments>http://www.softimageblog.com/archives/260#comments</comments>
		<pubDate>Tue, 20 May 2008 14:32:24 +0000</pubDate>
		<dc:creator>Helge Mathee</dc:creator>
				<category><![CDATA[JScript]]></category>
		<category><![CDATA[Modeling]]></category>
		<category><![CDATA[Programming / Scripting]]></category>

		<guid isPermaLink="false">http://www.xsi-blog.com/?p=260</guid>
		<description><![CDATA[So the keen folks at the german XSI forum (http://www.xsiforum.de) discussed the topic of generating separate objects out of all of the polygon islands making up a polygonmesh. Even though this doesn&#8217;t seem to be a too tricky scripting problem, using commands to achieve this split-up can slow down XSI quite alot, especially if the [...]]]></description>
			<content:encoded><![CDATA[<p>So the keen folks at the german XSI forum (<a href="http://www.xsiforum.de">http://www.xsiforum.de</a>) discussed the topic of generating separate objects out of all of the polygon islands making up a polygonmesh. Even though this doesn&#8217;t seem to be a too tricky scripting problem, using commands to achieve this split-up can slow down XSI quite alot, especially if the source mesh contains a huge amount of polygon islands. Therefore I tried to come up with a object oriented solution, and here it is.<br />
<span id="more-260"></span></p>
<p>I put some effort into commenting the script accordingly, so that it may be used for learning purposes.</p>
<p>cheers!</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// query the geometry data</span>
<span style="color: #003366; font-weight: bold;">var</span> obj <span style="color: #339933;">=</span> selection<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> geo <span style="color: #339933;">=</span> obj.<span style="color: #660066;">Activeprimitive</span>.<span style="color: #660066;">Geometry</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> polygons <span style="color: #339933;">=</span> geo.<span style="color: #660066;">Polygons</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// create an array to track which polygon has been visited</span>
<span style="color: #003366; font-weight: bold;">var</span> polygonVisited <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> polygonsLeft <span style="color: #339933;">=</span> polygons.<span style="color: #660066;">Count</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// fill up the array to say: &quot;no polygon has been visited yet&quot;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>polygons .<span style="color: #660066;">count</span><span style="color: #339933;">;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	polygonVisited<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// create some helper variables</span>
<span style="color: #003366; font-weight: bold;">var</span> clusterIndices <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> currentRow <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// log the start of the process</span>
logmessage<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Starting with &quot;</span><span style="color: #339933;">+</span>polygonsLeft<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot; polygons...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// loop until there are no polygons left</span>
<span style="color: #006600; font-style: italic;">// or there are still items in the cluster array</span>
<span style="color: #000066; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span>polygonsLeft <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">||</span> clusterIndices.<span style="color: #660066;">length</span> <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #006600; font-style: italic;">// if there are no items in the next row...</span>
	<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>currentRow.<span style="color: #660066;">length</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #006600; font-style: italic;">// if there are items in the cluster index array</span>
		<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>clusterIndices.<span style="color: #660066;">length</span> <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #006600; font-style: italic;">// log the creation of the cluster</span>
			logmessage<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Creating cluster with &quot;</span><span style="color: #339933;">+</span>clusterIndices.<span style="color: #660066;">length</span><span style="color: #339933;">+</span><span style="color: #3366CC;">&quot; elements...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #006600; font-style: italic;">// create a new mesh containing all of these polygons</span>
			<span style="color: #006600; font-style: italic;">// first, create an array containing all pointindices</span>
			<span style="color: #006600; font-style: italic;">// and two additional point hash arrays</span>
			<span style="color: #006600; font-style: italic;">// of which one is used to determine if a point is already used</span>
			<span style="color: #006600; font-style: italic;">// and the second one is used to map the original index to the new one</span>
			<span style="color: #003366; font-weight: bold;">var</span> pointIndices <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #003366; font-weight: bold;">var</span> pointUsed <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #003366; font-weight: bold;">var</span> pointNewIndex <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>clusterIndices.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				<span style="color: #003366; font-weight: bold;">var</span> poly <span style="color: #339933;">=</span> polygons.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#40;</span>clusterIndices<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #003366; font-weight: bold;">var</span> pointIndexArray <span style="color: #339933;">=</span> poly.<span style="color: #660066;">points</span>.<span style="color: #660066;">indexArray</span>.<span style="color: #660066;">toArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//(VBS to JScript conversion)</span>
&nbsp;
				<span style="color: #006600; font-style: italic;">// loop through all points and check if it they are used</span>
				<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> j<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>j<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>pointIndexArray.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
				<span style="color: #009900;">&#123;</span>
					<span style="color: #003366; font-weight: bold;">var</span> index <span style="color: #339933;">=</span> pointIndexArray<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
					<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>pointUsed<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
					<span style="color: #009900;">&#123;</span>
						pointNewIndex<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> pointIndices.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
						pointIndices.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>index<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
						pointUsed<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>	
					<span style="color: #009900;">&#125;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
			<span style="color: #006600; font-style: italic;">// now, create the array of the positions of all points of this island</span>
			<span style="color: #003366; font-weight: bold;">var</span> islandPos <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>pointIndices.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				<span style="color: #003366; font-weight: bold;">var</span> point <span style="color: #339933;">=</span> geo.<span style="color: #660066;">points</span>.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#40;</span>pointIndices<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				islandPos.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>point.<span style="color: #660066;">position</span>.<span style="color: #660066;">x</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				islandPos.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>point.<span style="color: #660066;">position</span>.<span style="color: #660066;">y</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				islandPos.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>point.<span style="color: #660066;">position</span>.<span style="color: #660066;">z</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
			<span style="color: #006600; font-style: italic;">// now we need to create the description of the polygons</span>
			<span style="color: #003366; font-weight: bold;">var</span> islandPoly <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #006600; font-style: italic;">// for that we loop over the polygons of the island again</span>
			<span style="color: #006600; font-style: italic;">// and record their pointindices, well, actually the remapped</span>
			<span style="color: #006600; font-style: italic;">// indices (given by the pointNewIndex hash array)</span>
			<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>clusterIndices.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				<span style="color: #003366; font-weight: bold;">var</span> poly <span style="color: #339933;">=</span> polygons.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#40;</span>clusterIndices<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #003366; font-weight: bold;">var</span> pointIndexArray <span style="color: #339933;">=</span> poly.<span style="color: #660066;">points</span>.<span style="color: #660066;">indexArray</span>.<span style="color: #660066;">toArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//(VBS to JScript conversion)</span>
&nbsp;
				<span style="color: #006600; font-style: italic;">// first add the number of points of this polygon </span>
				<span style="color: #006600; font-style: italic;">// to this polygon's description</span>
				islandPoly.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>pointIndexArray.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
				<span style="color: #006600; font-style: italic;">// now add the remapped index for each point to the description</span>
				<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> j<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>j<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>pointIndexArray.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
				<span style="color: #009900;">&#123;</span>
					<span style="color: #003366; font-weight: bold;">var</span> index <span style="color: #339933;">=</span> pointIndexArray<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
					islandPoly.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>pointNewIndex<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
			obj.<span style="color: #660066;">Parent</span>.<span style="color: #660066;">AddPolygonMesh</span><span style="color: #009900;">&#40;</span>islandPos<span style="color: #339933;">,</span>islandPoly<span style="color: #339933;">,</span>obj.<span style="color: #000066;">name</span><span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;_island&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			clusterIndices <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #006600; font-style: italic;">// if there are no polyons left we can stop now</span>
			<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>polygonsLeft <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
				<span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #006600; font-style: italic;">// loop over the polygons and try to find </span>
		<span style="color: #006600; font-style: italic;">// one which hasn't been visited yet</span>
		<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>polygons.<span style="color: #660066;">Count</span><span style="color: #339933;">;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>polygonVisited<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				currentRow.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				clusterIndices.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				polygonVisited<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
				polygonsLeft<span style="color: #339933;">--;</span>
				<span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">// define the nextrow after the current row</span>
	<span style="color: #003366; font-weight: bold;">var</span> nextRow <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">// loop over all items in the current row</span>
	<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>currentRow.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> polygon <span style="color: #339933;">=</span> polygons.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#40;</span>currentRow<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> neighbors <span style="color: #339933;">=</span> polygon.<span style="color: #660066;">NeighborPolygons</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #006600; font-style: italic;">// loop through all of the neighbors and add them to the nextRow</span>
		<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> j<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>j<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>neighbors.<span style="color: #660066;">count</span><span style="color: #339933;">;</span>j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #006600; font-style: italic;">// check if the neighbor has been</span>
			<span style="color: #006600; font-style: italic;">// visited yet</span>
			<span style="color: #003366; font-weight: bold;">var</span> neighbor <span style="color: #339933;">=</span> neighbors.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#40;</span>j<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">index</span><span style="color: #339933;">;</span>
			<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>polygonVisited<span style="color: #009900;">&#91;</span>neighbor<span style="color: #009900;">&#93;</span><span style="color: #339933;">==</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				<span style="color: #006600; font-style: italic;">// add the neighbor to the next row</span>
				nextRow.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>neighbor<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				clusterIndices.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>neighbor<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				polygonVisited<span style="color: #009900;">&#91;</span>neighbor<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
				polygonsLeft<span style="color: #339933;">--;</span>
				<span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	currentRow <span style="color: #339933;">=</span> nextRow<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
selection.<span style="color: #660066;">SetAsText</span><span style="color: #009900;">&#40;</span>obj.<span style="color: #000066;">name</span><span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;_island*&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<img src="http://www.softimageblog.com/?ak_action=api_record_view&id=260&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.softimageblog.com/archives/260/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>FCurves As Shading Tools&#8230;</title>
		<link>http://www.softimageblog.com/archives/200#utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=fcurves-as-shaders</link>
		<comments>http://www.softimageblog.com/archives/200#comments</comments>
		<pubDate>Fri, 30 Mar 2007 04:33:35 +0000</pubDate>
		<dc:creator>Stefano Jannuzzo</dc:creator>
				<category><![CDATA[JScript]]></category>
		<category><![CDATA[Rendering]]></category>

		<guid isPermaLink="false">http://www.xsi-blog.com/archives/200</guid>
		<description><![CDATA[Let&#8217;s look at a short technique that will allow you to export any custom function curve or scripting math function to a texturable node to be used in the rendertree.
Let&#8217;s get a curve
We start by taking a poly strip, with a 100&#215;1 subdivisions. This will be our &#8220;drawing&#8221; table. We then make a cluster of [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s look at a short technique that will allow you to export any custom function curve or scripting math function to a texturable node to be used in the rendertree.</p>
<p><strong>Let&#8217;s get a curve</strong></p>
<p>We start by taking a poly strip, with a 100&#215;1 subdivisions. This will be our &#8220;drawing&#8221; table. We then make a cluster of the whole set of points, and give it a weightmap. The range for the weights is set as wide as possible (-100, 100) to allow for both large positive and negative values. We then apply to the grid a custom property with a profile function curve, which you can then shape as you wish.</p>
<p>Here is a script that will do the steps mentioned above.</p>
<p><span id="more-200"></span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> CreateGrid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">//create a poly strand, 100x1</span>
    <span style="color: #003366; font-weight: bold;">var</span> grid <span style="color: #339933;">=</span> CreatePrim<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Grid&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;MeshSurface&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    SetValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grid.grid.ulength&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    SetValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grid.grid.vlength&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    SetValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grid.polymsh.geom.subdivu&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    SetValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grid.polymsh.geom.subdivv&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">//create the cluster</span>
    SelectGeometryComponents<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grid.pnt[*]&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    CreateCluster<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">//apply a weightmap</span>
    CreateWeightMap<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;Weight_Map&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    SetValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grid.polymsh.cls.Point.Weight_Map.red&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    SetValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grid.polymsh.cls.Point.Weight_Map.blue&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    SetValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grid.polymsh.cls.Point.Weight_Map.green&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">//allow for large min and max weights</span>
    SetValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grid.polymsh.cls.Point.Weight_Map.weightmapop.wmin&quot;</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">100</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    SetValue<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grid.polymsh.cls.Point.Weight_Map.weightmapop.wmax&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">return</span> grid<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> ApplyProfile<span style="color: #009900;">&#40;</span>grid<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> oCPSet <span style="color: #339933;">=</span> grid.<span style="color: #660066;">AddProperty</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;CustomProperty&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;ProfilePSet&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> oFCParam <span style="color: #339933;">=</span> oCPSet.<span style="color: #660066;">AddFCurveParameter</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ProfileFC&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> oFCurve <span style="color: #339933;">=</span> oFCParam.<span style="color: #660066;">Value</span><span style="color: #339933;">;</span>
&nbsp;
    oFCurve.<span style="color: #660066;">SetKeys</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0.25</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0.5</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">0.5</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0.75</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0.8</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> grid <span style="color: #339933;">=</span> CreateGrid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ApplyProfile<span style="color: #009900;">&#40;</span>grid<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><a href='/userContent/upload/2007/03/fm1.jpg' title='fm1.jpg'><img src='/userContent/upload/2007/03/fm1.jpg' alt='fm1.jpg' width='600' /></a></p>
<p><strong>Sampling the curve</strong></p>
<p>This is done by the following script.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> SampleFunction<span style="color: #009900;">&#40;</span>pSet<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> par <span style="color: #339933;">=</span> pSet.<span style="color: #660066;">NestedObjects</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> fC <span style="color: #339933;">=</span> par.<span style="color: #660066;">value</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> pArray <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> vArray <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">//fcurve min and max range</span>
    <span style="color: #003366; font-weight: bold;">var</span> rangeMin <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> rangeMax <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> range <span style="color: #339933;">=</span> rangeMax <span style="color: #339933;">-</span> rangeMin<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> x<span style="color: #339933;">,</span> y<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">//number of samples, equal to the grid number of points along x</span>
    <span style="color: #003366; font-weight: bold;">var</span> nbSamples <span style="color: #339933;">=</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span> <span style="color: #339933;">=</span>nbSamples<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">//i-th column of points</span>
        pArray<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">*</span><span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
        pArray<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">*</span><span style="color: #CC0000;">2</span> <span style="color: #339933;">+</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
&nbsp;
        x <span style="color: #339933;">=</span> rangeMin <span style="color: #339933;">+</span> range <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">/</span>nbSamples<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        y <span style="color: #339933;">=</span> fC.<span style="color: #000066; font-weight: bold;">Eval</span><span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//value of the function at x</span>
&nbsp;
        vArray<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> vArray<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> y<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//values for the weight map</span>
&nbsp;
        <span style="color: #006600; font-style: italic;">//set the weights for the i-th column of points</span>
        PaintWeights<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grid.polymsh.cls.Point.Weight_Map&quot;</span><span style="color: #339933;">,</span> pArray<span style="color: #339933;">,</span> vArray<span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//select the ProfilePSet first</span>
<span style="color: #003366; font-weight: bold;">var</span> profilePSet <span style="color: #339933;">=</span> selection<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
SampleFunction<span style="color: #009900;">&#40;</span>profilePSet<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>You just have to take care of setting the current range min and max correctly and then run it with the ProfilePSet. The script will simply sample the curve with the same rate as the grid subdivisions along x. The grid has 101 column of points along the x. We take the corresponding function values and stick them on the weightmap. Note that we&#8217;re using 100 samples, but we could have used much more for both the grid and the sampling rate.</p>
<p><strong>Plotting the weightmap</strong></p>
<p><a href='/userContent/upload/2007/03/fm2.jpg' title='fm2.jpg'><img src='/userContent/upload/2007/03/fm2.jpg' alt='fm2.jpg' width='600'/></a></p>
<p>We apply a color sampler lightmap shader. The input color to be sampled comes from a scalar lookup of the weightmap.</p>
<p>The writable map must be a hdr one (float .ct is my choice), in order to allow for large positive and negative values to be stored. Only the X resolution matters, since we are basically plotting a mono dimensional texture. The map is applied with a xz projection over the grid. You now just need to fire a tiny render region to have the lighmap written.</p>
<p><strong>Reusing the map</strong></p>
<p>As said, the map is one dimensional, so only the u matters when you look it up. So, if you pick a share vector node and connect it to an image lookup, the x coordinate of the vector acts as the input you are remapping by the original function curve. In this example, the lookup feeds the displacement, being the value to be remapped coming from a standard uv projection over the new grid.</p>
<p><a href='/userContent/upload/2007/03/fm3.jpg' title='fm3.jpg'><img src='/userContent/upload/2007/03/fm3.jpg' alt='fm3.jpg' width='600'/></a></p>
<p>What is important is to remember the range the function was originally sampled over, that must match the expected range of the value (the u coordinate in this example) you are going to remap.</p>
<p><strong>Sampling a scripting function</strong></p>
<p>As mentioned, you can also use this approach to paint any math function provided by your scripting function. Instead of using a function curve, you can simply loop and evaluate the desired function.</p>
<p>For instance, this is how you sample and weight paint a sin function in the -pi +pi range:</p>
</pre>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> SampleSin<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> pArray <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> vArray <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> rangeMin <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">3.14159</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> rangeMax <span style="color: #339933;">=</span> <span style="color: #CC0000;">3.14159</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> range <span style="color: #339933;">=</span> rangeMax <span style="color: #339933;">-</span> rangeMin<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> x<span style="color: #339933;">,</span> y<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> nbSamples <span style="color: #339933;">=</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span> <span style="color: #339933;">=</span>nbSamples<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        pArray<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">*</span><span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
        pArray<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">*</span><span style="color: #CC0000;">2</span> <span style="color: #339933;">+</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
&nbsp;
        x <span style="color: #339933;">=</span> rangeMin <span style="color: #339933;">+</span> range <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">/</span>nbSamples<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        y <span style="color: #339933;">=</span> Math.<span style="color: #660066;">sin</span><span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//value of the function at x</span>
&nbsp;
        vArray<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> vArray<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> y<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//values for the weight map</span>
&nbsp;
        PaintWeights<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grid.polymsh.cls.Point.Weight_Map&quot;</span><span style="color: #339933;">,</span> pArray<span style="color: #339933;">,</span> vArray<span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

</pre>
<img src="http://www.softimageblog.com/?ak_action=api_record_view&id=200&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.softimageblog.com/archives/200/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A tool for visualising particle distributions</title>
		<link>http://www.softimageblog.com/archives/198#utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-tool-for-visualising-particle-distributions</link>
		<comments>http://www.softimageblog.com/archives/198#comments</comments>
		<pubDate>Sun, 18 Mar 2007 13:04:19 +0000</pubDate>
		<dc:creator>Andy Nicholas</dc:creator>
				<category><![CDATA[JScript]]></category>
		<category><![CDATA[Programming / Scripting]]></category>
		<category><![CDATA[Simulation]]></category>

		<guid isPermaLink="false">http://www.xsi-blog.com/archives/198</guid>
		<description><![CDATA[Some of you may remember the Histogram plugin that I wrote for XSI&#8217;s rendertree. It&#8217;s a tool for visualising exactly what is happening in your shading networks and can be invaluable when trying to find out why your shader is behaving unexpectedly.
Since the Histogram display window is just a COM application launched by the equivalent [...]]]></description>
			<content:encoded><![CDATA[<p>Some of you may remember the Histogram plugin that I wrote for XSI&#8217;s rendertree. It&#8217;s a tool for visualising exactly what is happening in your shading networks and can be invaluable when trying to find out why your shader is behaving unexpectedly.</p>
<p>Since the Histogram display window is just a COM application launched by the equivalent mental ray shader, there&#8217;s nothing stopping you using the Histogram display tool for other uses. Indeed, I included in the original download example source scripts to demonstrate how to drive the COM interface.</p>
<p>Vince Fortin has asked me about whether it&#8217;s possible to get Histogram to show distributions for particle systems. So at his request (thanks for reminding me Vince!) I&#8217;m posting some example code to show you how to do it.</p>
<p>First though, here&#8217;s a quick screen shot of the sort of information it can show:</p>
<p align="center"><a href="/userContent/upload/2007/03/pdistribution.jpg" title="Histogram for particles"><img src="/userContent/upload/2007/03/pdistribution.thumbnail.jpg" alt="Histogram for particles" /></a></p>
<p align="left">Here I&#8217;m using Histogram to show the distribution of the X, Y, and Z positions of the particles. I&#8217;ve also got it to display the particle age too. Note that the number of samples (1853) shown at the bottom, actually corresponds to the number of particles.</p>
<p><span id="more-198"></span>The JScript code below features a reusable object called <strong>HistogramData</strong>. This object has a member function called <strong>ProcessSample()</strong> which will take a sample value and take care of the histogram construction for you. You then push the <strong>curHist </strong>member to the Histogram COM application for display.</p>
<p>The first function in the code is a script callback for a particle event. To make it work, you just need to add a particle event to a PType and create an <strong>OnEveryFrame</strong> event with the trigger value set to 0 so that the script gets called every frame. You can then control the execution of the Histogram display inside the script by changing the trigger frame number.</p>
<p>You can download and find out more about Histogram by following this link:</p>
<p><a href="http://www.andynicholas.com/thezone/index.php?area=downloadinfo&amp;app=XSI&amp;file=2">www.andynicholas.com -&gt; Histogram</a></p>
<p>Please feel free to modify this code for your own usage.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> HISTOGRAM_RES <span style="color: #339933;">=</span> <span style="color: #CC0000;">256</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> INV_HISTOGRAM_RES <span style="color: #339933;">=</span> <span style="color: #CC0000;">0.00390625</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> HISTOGRAM_ARRSIZE <span style="color: #339933;">=</span> <span style="color: #CC0000;">257</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> OnEveryFrame<span style="color: #009900;">&#40;</span>inParticleCloud<span style="color: #339933;">,</span> inTriggerParticleIndices<span style="color: #339933;">,</span> inSimFrame<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #006600; font-style: italic;">//Frame 99 is when the distribution will be viewed, and</span>
<span style="color: #006600; font-style: italic;">//you can change it to whatever you want.</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//Note that if you persist the histogram data objects, there's no</span>
<span style="color: #006600; font-style: italic;">//reason you can't gather distributions across multiple frames.</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//To make things a little easier to adjust, you may also want to</span>
<span style="color: #006600; font-style: italic;">//create a custom property in the scene to tie this frame value to.</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>inSimFrame<span style="color: #339933;">==</span><span style="color: #CC0000;">99</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #006600; font-style: italic;">//Initialise the data</span>
<span style="color: #003366; font-weight: bold;">var</span> histx <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> HistogramData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> histy <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> HistogramData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> histz <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> HistogramData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> histage <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> HistogramData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//This is where we store the data whose distribution we want to look at.</span>
<span style="color: #006600; font-style: italic;">//In this case, we're observing position and age.</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> particles <span style="color: #339933;">=</span> inParticleCloud.<span style="color: #660066;">particles</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> num_particles <span style="color: #339933;">=</span> particles.<span style="color: #660066;">count</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>num_particles<span style="color: #339933;">;++</span>i<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #003366; font-weight: bold;">var</span> particle <span style="color: #339933;">=</span> particles<span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
histx.<span style="color: #660066;">ProcessSample</span><span style="color: #009900;">&#40;</span>particle.<span style="color: #660066;">position</span>.<span style="color: #660066;">x</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
histy.<span style="color: #660066;">ProcessSample</span><span style="color: #009900;">&#40;</span>particle.<span style="color: #660066;">position</span>.<span style="color: #660066;">y</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
histz.<span style="color: #660066;">ProcessSample</span><span style="color: #009900;">&#40;</span>particle.<span style="color: #660066;">position</span>.<span style="color: #660066;">z</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
histage.<span style="color: #660066;">ProcessSample</span><span style="color: #009900;">&#40;</span>particle.<span style="color: #660066;">age</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//Display the data</span>
<span style="color: #003366; font-weight: bold;">var</span> histWindow <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> ActiveXObject<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;HistogramDisplay.Application&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
histWindow.<span style="color: #660066;">SetHistogram</span><span style="color: #009900;">&#40;</span>histx.<span style="color: #660066;">curHist</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;Pos.X&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> histx.<span style="color: #660066;">min</span><span style="color: #339933;">,</span> histx.<span style="color: #660066;">max</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
histWindow.<span style="color: #660066;">SetHistogram</span><span style="color: #009900;">&#40;</span>histy.<span style="color: #660066;">curHist</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;Pos.Y&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> histy.<span style="color: #660066;">min</span><span style="color: #339933;">,</span> histy.<span style="color: #660066;">max</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
histWindow.<span style="color: #660066;">SetHistogram</span><span style="color: #009900;">&#40;</span>histz.<span style="color: #660066;">curHist</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;Pos.Z&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> histz.<span style="color: #660066;">min</span><span style="color: #339933;">,</span> histz.<span style="color: #660066;">max</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
histWindow.<span style="color: #660066;">SetHistogram</span><span style="color: #009900;">&#40;</span>histage.<span style="color: #660066;">curHist</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;Age&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">,</span> histage.<span style="color: #660066;">min</span><span style="color: #339933;">,</span> histage.<span style="color: #660066;">max</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
histWindow.<span style="color: #660066;">SetHistogramColor</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">80</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
histWindow.<span style="color: #660066;">SetHistogramColor</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">80</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
histWindow.<span style="color: #660066;">SetHistogramColor</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">80</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
histWindow.<span style="color: #660066;">SetHistogramColor</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">3</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
histWindow.<span style="color: #660066;">SetNumToDisplay</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
histWindow.<span style="color: #660066;">UpdateWindow</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//Data object representing histogram data</span>
<span style="color: #006600; font-style: italic;">//and contains member function called ProcessSample()</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> HistogramData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">min</span><span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">max</span><span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">samples</span><span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">curHist</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">&#40;</span>HISTOGRAM_ARRSIZE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">otherHist</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">&#40;</span>HISTOGRAM_ARRSIZE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>HISTOGRAM_ARRSIZE<span style="color: #339933;">;++</span>i<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">curHist</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">otherHist</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">ProcessSample</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>sample<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #006600; font-style: italic;">//This function does all the hard work</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//It is a direct port from C++ of the functionality</span>
<span style="color: #006600; font-style: italic;">//of the original Histogram rendertree shader</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> oldMin <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">min</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> oldMax <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">max</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> oldBucketSize <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>oldMax<span style="color: #339933;">-</span>oldMin<span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span>INV_HISTOGRAM_RES<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> scaleChanged<span style="color: #339933;">=</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">samples</span><span style="color: #339933;">==</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">min</span> <span style="color: #339933;">=</span> sample<span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">max</span> <span style="color: #339933;">=</span> sample<span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">samples</span><span style="color: #339933;">++;</span>
<span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>sample<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>this.<span style="color: #660066;">min</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">min</span> <span style="color: #339933;">=</span> sample<span style="color: #339933;">;</span>
scaleChanged<span style="color: #339933;">=</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>sample<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span>this.<span style="color: #660066;">max</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">max</span> <span style="color: #339933;">=</span> sample<span style="color: #339933;">;</span>
scaleChanged<span style="color: #339933;">=</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">samples</span><span style="color: #339933;">==</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">curHist</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">++;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">curHist</span><span style="color: #009900;">&#91;</span>HISTOGRAM_RES<span style="color: #009900;">&#93;</span><span style="color: #339933;">++;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">samples</span><span style="color: #339933;">++;</span>
<span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> bucketSize <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">max</span><span style="color: #339933;">-</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">min</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span>INV_HISTOGRAM_RES<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> rangeRatio <span style="color: #339933;">=</span> HISTOGRAM_RES<span style="color: #339933;">/</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">max</span><span style="color: #339933;">-</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">min</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">max</span><span style="color: #339933;">-</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">min</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">==</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> rangeRatio<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>scaleChanged<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #006600; font-style: italic;">//Swap histograms</span>
<span style="color: #003366; font-weight: bold;">var</span> tempHist<span style="color: #339933;">;</span>
tempHist <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">curHist</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">curHist</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">otherHist</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">otherHist</span> <span style="color: #339933;">=</span> tempHist<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//Copy and rescale the histogram according to the new sample and resample</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>HISTOGRAM_ARRSIZE<span style="color: #339933;">;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #006600; font-style: italic;">//Calculate sample value</span>
<span style="color: #003366; font-weight: bold;">var</span> value <span style="color: #339933;">=</span> oldMin <span style="color: #339933;">+</span> oldBucketSize<span style="color: #339933;">*</span>i<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//Calculate new bucket</span>
<span style="color: #003366; font-weight: bold;">var</span> newBucket <span style="color: #339933;">=</span> Math.<span style="color: #660066;">floor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>value <span style="color: #339933;">-</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">min</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span>rangeRatio<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>newBucket<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> newBucket<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>newBucket<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;=</span>HISTOGRAM_ARRSIZE<span style="color: #009900;">&#41;</span> newBucket<span style="color: #339933;">=</span>HISTOGRAM_ARRSIZE<span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">curHist</span><span style="color: #009900;">&#91;</span>newBucket<span style="color: #009900;">&#93;</span><span style="color: #339933;">+=</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">otherHist</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">otherHist</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//Add sample</span>
<span style="color: #003366; font-weight: bold;">var</span> inputBucket <span style="color: #339933;">=</span> Math.<span style="color: #660066;">floor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>sample <span style="color: #339933;">-</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">min</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span>rangeRatio<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>inputBucket<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> inputBucket<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>inputBucket<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;=</span>HISTOGRAM_ARRSIZE<span style="color: #009900;">&#41;</span> inputBucket<span style="color: #339933;">=</span>HISTOGRAM_ARRSIZE<span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">curHist</span><span style="color: #009900;">&#91;</span>inputBucket<span style="color: #009900;">&#93;</span><span style="color: #339933;">++;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">samples</span><span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<img src="http://www.softimageblog.com/?ak_action=api_record_view&id=198&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.softimageblog.com/archives/198/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Custom Properties Persistent Layout</title>
		<link>http://www.softimageblog.com/archives/172#utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=custom-properties-persistent-layout</link>
		<comments>http://www.softimageblog.com/archives/172#comments</comments>
		<pubDate>Fri, 02 Feb 2007 05:28:19 +0000</pubDate>
		<dc:creator>Daniele Niero</dc:creator>
				<category><![CDATA[JScript]]></category>
		<category><![CDATA[Programming / Scripting]]></category>

		<guid isPermaLink="false">http://www.xsi-blog.com/archives/172</guid>
		<description><![CDATA[From a rigger&#8217;s point of view, I think Softimage&#124;XSI is one of the best software around, and as character TD, I really love proxy parameters. The possibility to expose to animators every channel we want can make our rigs definitely cleaner, more understandable and easier to use. On the other hand a simple list of [...]]]></description>
			<content:encoded><![CDATA[<p>From a rigger&#8217;s point of view, I think Softimage|XSI is one of the best software around, and as character TD, I really love proxy parameters. The possibility to expose to animators every channel we want can make our rigs definitely cleaner, more understandable and easier to use. On the other hand a simple list of parameters can be long and hard to read.</p>
<p>Fortunately XSI gives us the possibility to customize a custom property&#8217;s layout with groups, tabs, by changing the parameter&#8217;s aspect, and replicating them as many times as we wish.</p>
<p>Unfortunately these layout informations are not persisted with the scene which means they are forgotten from one XSI session to another.</p>
<p><span id="more-172"></span><strong>The idea</strong></p>
<p>To bypass this problem I wrote a self installing custom property in JScript. The property has a string parameter where I can write my layout code and the property can read it and change itself. Because this code is actually a parameter&#8217;s value it is saved in the scene which means we are not going to loose the layout.</p>
<p><strong>A look at the code</strong></p>
<p>The first thing we need to create is a plugin that registers a new property. We can use the wizard in XSI to do this and call the new property whatever we want. I called it GenericProperty because, well, it&#8217;s generic.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> XSILoadPlugin<span style="color: #009900;">&#40;</span>in_reg<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	in_reg.<span style="color: #660066;">Author</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;Daniele Niero&quot;</span><span style="color: #339933;">;</span>
	in_reg.<span style="color: #000066;">Name</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;GenericProperty_Plugin&quot;</span><span style="color: #339933;">;</span>
	in_reg.<span style="color: #660066;">Major</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
	in_reg.<span style="color: #660066;">Minor</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
	in_reg.<span style="color: #660066;">RegisterProperty</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;GenericProperty&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> GenericProperty_Define<span style="color: #009900;">&#40;</span>io_Context<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> oCustomProperty<span style="color: #339933;">;</span>
	oCustomProperty <span style="color: #339933;">=</span> io_Context.<span style="color: #660066;">Source</span><span style="color: #339933;">;</span>
	oCustomProperty.<span style="color: #660066;">AddParameter2</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;PropertyCode&quot;</span><span style="color: #339933;">,</span>siString<span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>siPersistable<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	oCustomProperty.<span style="color: #660066;">AddParameter2</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;PropertyPPGTab&quot;</span><span style="color: #339933;">,</span> siBool<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>The trick is performed in the OnInit function</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> GenericProperty_OnInit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> oLayout <span style="color: #339933;">=</span> PPG.<span style="color: #660066;">PPGLayout</span><span style="color: #339933;">;</span>
	<span style="color: #003366; font-weight: bold;">var</span> startCode <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;function ChangeProperty(){<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;oLayout.Clear();<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #003366; font-weight: bold;">var</span> userCode <span style="color: #339933;">=</span> PPG.<span style="color: #660066;">PropertyCode</span>.<span style="color: #660066;">Value</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>PPG.<span style="color: #660066;">PropertyPPGTab</span>.<span style="color: #660066;">Value</span> <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> endCode <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;oLayout.AddTab(<span style="color: #000099; font-weight: bold;">\&quot;</span>PPG<span style="color: #000099; font-weight: bold;">\&quot;</span>);<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;oLayout.AddItem(<span style="color: #000099; font-weight: bold;">\&quot;</span>PropertyPPGTab<span style="color: #000099; font-weight: bold;">\&quot;</span>);<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;oLayout.AddString(<span style="color: #000099; font-weight: bold;">\&quot;</span>PropertyCode<span style="color: #000099; font-weight: bold;">\&quot;</span>,<span style="color: #000099; font-weight: bold;">\&quot;</span>PropertyCode<span style="color: #000099; font-weight: bold;">\&quot;</span>, true, 500);<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;}&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>PPG.<span style="color: #660066;">PropertyPPGTab</span>.<span style="color: #660066;">Value</span> <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> endCode <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;}&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #003366; font-weight: bold;">var</span> code <span style="color: #339933;">=</span> startCode <span style="color: #339933;">+</span> userCode <span style="color: #339933;">+</span> endCode<span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span>code<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	ChangeProperty<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	PPG.<span style="color: #660066;">Refresh</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>There are three important variables in this code <strong>startCode</strong>, <strong>endCode</strong> and especially <strong>userCode.</strong> They are strings that define the layout code.</p>
<p><strong>startCode</strong> is a constant and it will never change. As you can see it defines a function called <strong>ChangeProperty()</strong>, all the rest of the code is part of this function.</p>
<p><strong>userCode</strong> defines the code that creates a tab called <strong>PropertyPPGTab</strong> with a parameter called <strong>PropertyCode</strong> and then closes the <strong>ChangeProperty</strong> function. The tab is defined only if <strong>PropertyPPGTab</strong> is true, allowing us to hide <strong>PropertyCode</strong> Errors are thus prevented as the custom property is left perfectly clean and animators aren&#8217;t scared with strange code they normally don&#8217;t want to see.</p>
<p><strong>userCode</strong> is the variable we are interested in. It is filled with the value of the <strong>PropertyCode</strong> parameter and in this parameter we can write our layout code directly from the property in XSI.</p>
<p>At the end all these three variables are connected together in a single one called <strong>code</strong> and evaluated with the <strong>eval</strong> function. If <strong>code</strong> doesn&#8217;t contain any syntax errors <strong>eval</strong> will evaluate it successfully and we can then call the <strong>ChangeProperty()</strong> function to have it create our layout.</p>
<p>Final touch, <strong>PPG.Refresh()</strong> ensures a correct layout refresh.</p>
<p><strong>How use it</strong></p>
<p>Very simple, just load the plugin in XSI and apply this property on an object, open it and create some custom parameters or proxy parameters as usual and start to write your layout.</p>
<p>For example imagine you have two parameters (custom or proxy doesn&#8217;t make any difference) named Param1 and Param2.</p>
<p>We can write a layout like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">oLayout.<span style="color: #660066;">AddGroup</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;First Parameter&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	oLayout.<span style="color: #660066;">AddItem</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Param1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
oLayout.<span style="color: #660066;">EndGroup</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
oLayout.<span style="color: #660066;">AddGroup</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Second Parameter&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	oLayout.<span style="color: #660066;">AddItem</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Param2&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
oLayout.<span style="color: #660066;">EndGroup</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
oLayout.<span style="color: #660066;">AddTab</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;A Tab&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	oLayout.<span style="color: #660066;">AddItem</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Param1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	oLayout.<span style="color: #660066;">AddItem</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Param2&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Refresh or just reopen the property and you should be able to see your layout.</p>
<p><strong>Limitation</strong></p>
<p>I have been using this solution from almost two years now and it has worked really well so far. Recently I wanted to improve it a little bit and I tried to implement the possibility to write a logic session as well.</p>
<p>Unfortunately it seemed impossible to make the logic as dynamic as the layout. I had problems flushing and regenerating the Logic even if using <code>oLayout.Delete()</code> instead of just <code>Clear()</code>.</p>
<img src="http://www.softimageblog.com/?ak_action=api_record_view&id=172&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.softimageblog.com/archives/172/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Geometry + Rig / RefModels in 6.0</title>
		<link>http://www.softimageblog.com/archives/169#utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=geometry-rig-refmodels-in-60</link>
		<comments>http://www.softimageblog.com/archives/169#comments</comments>
		<pubDate>Thu, 01 Feb 2007 16:43:44 +0000</pubDate>
		<dc:creator>Helge Mathee</dc:creator>
				<category><![CDATA[JScript]]></category>
		<category><![CDATA[Rigging]]></category>
		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.xsi-blog.com/archives/169</guid>
		<description><![CDATA[After a couple of chit chats about referenced models in 6.0, I would take to take a few minutes to explain how you can use the delta referencing system to separate rig and geometry into two different files, which can be edited independently from one another.


Okay so here&#8217;s how it works:

Create your geometry and rig
Put [...]]]></description>
			<content:encoded><![CDATA[<p>After a couple of chit chats about referenced models in 6.0, I would take to take a few minutes to explain how you can use the delta referencing system to separate rig and geometry into two different files, which can be edited <strong>independently</strong> from one another.</p>
<p><img src="http://www.xsi-blog.com/userContent/upload/2007/02/geo_rig_ref.jpg" alt="geo_rig_ref.jpg" /></p>
<p><span id="more-169"></span><br />
Okay so here&#8217;s how it works:</p>
<ol>
<li>Create your geometry and rig</li>
<li>Put rig and geometry into two different models</li>
<li>Create the connection (envelope, constraints etc)</li>
<li>Export <strong>FIRST</strong> the geometry, and <strong>SECOND</strong> the rig.</li>
<li>Go to a new scene and import <strong>FIRST</strong> the rig and <strong>SECOND</strong> the geometry as referenced models.</li>
<li>To ensure the models are loaded in the right order in the future, also name them alphabetically in that order. (in my example I am using numbers to set that order)</li>
<li>Put both ref models into a new one and export it as the &#8220;fullmodel&#8221;.</li>
</ol>
<p>You end up with three files. The first one includes just the geometry + envelope operator and weightmaps, the second one includes just the rig, and the third one, the &#8220;fullmodel&#8221;, includes just two file pointers to the previous two.</p>
<p>If you want to go ahead and make changes to the rig, you can externally, while just loading the rig up and modify it. If you are about to change the geometry, and you don&#8217;t want to loose the envelope, just open up the fullmodel, localize the submodels and do your edits, afterwards convert the geometry back to referenced, and reload the &#8220;fullmodel&#8221;.</p>
<p>Below you can see a working example in the explorer, and a repro script to generate this setup. All steps (also changes on the geometry after the connection has been established) are part of that script.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> project <span style="color: #339933;">=</span> ActiveProject.<span style="color: #660066;">path</span><span style="color: #339933;">;</span>
NewScene<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// create objects</span>
CreatePrim<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Cylinder&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;MeshSurface&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Create2DSkeleton<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0.5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
AppendBone<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;eff&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">3</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// create models</span>
CreateModel<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;root&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;_0rig&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
CreateModel<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;cylinder&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;_1geo&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// reset the transform of the models so</span>
<span style="color: #006600; font-style: italic;">// they are in the center of the world</span>
SetUserPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;SI3D_NODETRANSFORM_CHILD_COMPENSATE&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ResetTransform<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;_0rig&quot;</span><span style="color: #339933;">,</span> siObj<span style="color: #339933;">,</span> siSRT<span style="color: #339933;">,</span> siXYZ<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
SetUserPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;SI3D_NODETRANSFORM_CHILD_COMPENSATE&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// create the envelope (connect the rig)</span>
ApplyFlexEnv<span style="color: #009900;">&#40;</span>
<span style="color: #3366CC;">&quot;_1geo.cylinder;&quot;</span><span style="color: #339933;">+</span>
<span style="color: #3366CC;">&quot;_0rig.bone,_0rig.bone1&quot;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// export to files</span>
ExportModel<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;_1geo&quot;</span><span style="color: #339933;">,</span> project<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>Models<span style="color: #000099; font-weight: bold;">\\</span>geo.emdl&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ExportModel<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;_0rig&quot;</span><span style="color: #339933;">,</span> project<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>Models<span style="color: #000099; font-weight: bold;">\\</span>rig.emdl&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// new scene</span>
NewScene<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// import both as referenced</span>
SICreateRefModel<span style="color: #009900;">&#40;</span>project<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>Models<span style="color: #000099; font-weight: bold;">\\</span>rig.emdl&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;_0rig&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
SICreateRefModel<span style="color: #009900;">&#40;</span>project<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>Models<span style="color: #000099; font-weight: bold;">\\</span>geo.emdl&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;_1geo&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// create a new model including both</span>
CreateModel<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;_0rig,_1geo&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;fullmodel&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// export this model again</span>
ExportModel<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;fullmodel&quot;</span><span style="color: #339933;">,</span> project<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>Models<span style="color: #000099; font-weight: bold;">\\</span>fullmodel.emdl&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// new scene</span>
NewScene<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// import the fully rigged, separated model as referenced</span>
SICreateRefModel<span style="color: #009900;">&#40;</span>project<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>Models<span style="color: #000099; font-weight: bold;">\\</span>fullmodel.emdl&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;fullmodel&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// change the geometry while maintaining the connection</span>
MakeModelLocal<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;_0rig&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
MakeModelLocal<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;_1geo&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Translate<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;_1geo.cylinder.edge[67]&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1.5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ConvertToRefModel<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;_1geo&quot;</span><span style="color: #339933;">,</span> project <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>Models<span style="color: #000099; font-weight: bold;">\\</span>geo.emdl&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// reload the full model</span>
UpdateReferencedModel<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;fullmodel&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Here&#8217;s a <a href="http://www.xsi-blog.com/userContent/upload/2007/02/geo_rig_referenced.js" title="geo_rig_referenced.js">link</a> to the script file so you can download it and try it out.</p>
<p>I hope this helps!<br />
Helge</p>
<img src="http://www.softimageblog.com/?ak_action=api_record_view&id=169&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.softimageblog.com/archives/169/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Tricks with scripted particle events.</title>
		<link>http://www.softimageblog.com/archives/127#utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=tricks-with-scripted-particle-events</link>
		<comments>http://www.softimageblog.com/archives/127#comments</comments>
		<pubDate>Sun, 10 Dec 2006 17:01:15 +0000</pubDate>
		<dc:creator>Francois Lord</dc:creator>
				<category><![CDATA[JScript]]></category>
		<category><![CDATA[Programming / Scripting]]></category>
		<category><![CDATA[Simulation]]></category>

		<guid isPermaLink="false">http://www.xsi-blog.com/?p=127</guid>
		<description><![CDATA[I was recently assigned on a particle recipe that was going to be used by several people on several shots. After some thinking on how I was going to approach the idea, I realized that I needed a few features missing in XSI. In fact, I''ve been wanting those features many times in the past. I decided to take the time to write some scripted events, even though I was on a tight deadline. It turned out it was easier than I thought.]]></description>
			<content:encoded><![CDATA[<p>I was recently assigned on a particle recipe that was going to be used by several people on several shots. After some thinking on how I was going to approach the idea, I realized that I needed a few features missing in XSI. In fact, I&#8217;ve been wanting those features many times in the past. I decided to take the time to write some scripted events, even though I was on a tight deadline. It turned out it was easier than I thought.</p>
<p>I was required to create a bubble stream behind an underwater torpedo. Do torpedoes really have a stream of bubbles behind them in real life? In movies they do, so the question doesn&#8217;t really matter. I wanted to have many small bubbles and a few big bubbles within the same PType. I wanted to have the big bubbles rise faster than the small ones. I also wanted the bubbles to wobble as they were rising, and the wobble to be function of the size and the speed. Finally, I wanted the sprite sequence to begin at a random frame and continue normally as the particle aged. All this is not possible with the actual particle system in XSI 5.11, although they are common requirements in a simulation scene.</p>
<p><span id="more-127"></span><strong>The Distribution problem.</strong><br />
<img src="/userContent/upload/TricksParticleEvents_ExpDist.png" alt="Exponential Distribution" align="right" hspace="0" vspace="7"/><img src="/userContent/upload/TricksParticleEvents_ExpFunc.png" alt="Exponential Fuction" align="right" hspace="10" vspace="7"/> In XSI, you can only choose from uniform and Gaussian distribution. This means you can only have a middle value, and an equal probability on each side.  For what we need here, we will create a scripted event with the trigger on &#8220;Particle Age&#8221; at zero. We will name the event &#8220;<em>BirthControl</em>&#8220;. In the script tab, we set the language to JScript. It&#8217;s a shame we can&#8217;t use Python, since there are many cool random distributions in the standard library. The ScriptContext will be set to &#8220;Per Trigger Particle&#8221;. An exponent function will give a random distribution with a high probability at one end and a progressively lower probability towards the other end.</p>
<p>Size = (random number)5 * 0.025 + 0.005<br />
The &#8220;* 0.025&#8243; sets the difference in size between the biggest and the smallest bubbles.<br />
The &#8220;+ 0.005&#8243; sets the size of the smallest bubble size at 0.005 units. The biggest bubbles will be 0.03 units big.</p>
<p>In JScript, it&#8217;s written like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">inParticle.<span style="color: #660066;">Size</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">pow</span><span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">5</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">0.025</span> <span style="color: #339933;">+</span> <span style="color: #CC0000;">0.005</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>The object inParticle is given to the script by XSI and contains the current particle that triggered the event.</p>
<p><strong>The Speed from Size problem.</strong><br />
The size of the particles can be determined randomly. The effect of gravity can also be variable among the particles. But we can&#8217;t set a relation between the two with the tools in the UI. In fact, in scripting we don&#8217;t even have access to the effect of forces per particle. We will need to limit the length of the velocity vector according to the size of each particle. We must create a new scripted event called &#8220;<em>PerFrameControl</em>&#8221; with the trigger at &#8220;Every N Frame&#8221; and the value at 1. The ScriptContext will be &#8220;Per Particle&#8221;.</p>
<p>If a particle&#8217;s speed exceeds the product of it&#8217;s size and a coefficient, bring it back to that product.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">speed <span style="color: #339933;">=</span> inParticle.<span style="color: #660066;">Velocity</span><span style="color: #339933;">;</span>
size <span style="color: #339933;">=</span> inParticle.<span style="color: #660066;">Size</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>speed.<span style="color: #660066;">Length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> size <span style="color: #339933;">*</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>  <span style="color: #006600; font-style: italic;">// if speed is bigger than 10 times the size...</span>
    speed.<span style="color: #660066;">NormalizeInPlace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>      <span style="color: #006600; font-style: italic;">// scale the speed to be 1 and</span>
    speed.<span style="color: #660066;">ScaleInPlace</span><span style="color: #009900;">&#40;</span>size <span style="color: #339933;">*</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// scale speed to be 10 times the size.</span>
<span style="color: #009900;">&#125;</span>
inParticle.<span style="color: #660066;">Velocity</span> <span style="color: #339933;">=</span> speed<span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>This has the advantage that a particle will have no speed at its birth, and slowly accelerate from the effect of gravity. It will continue to accelerate until it reaches the speed it is allowed. Then it will keep this speed forever unless it has to decelerate, which shouldn&#8217;t happen in our scene.</p>
<p><strong>The Wobble Problem</strong><br />
There is already some perlin noise in the PType to make the bubbles rise in a natural fashion and we don&#8217;t want to lose that. We can&#8217;t add a small brownian noise to simulate the wobble and even if we could, we couldn&#8217;t link it to the size and speed of the particles. Without going into complicated wobble behavior, we will simply randomize the particle position in X and Z over time.</p>
<p>Generate a vector that has a random value for the X and Z axes, and multiply that value by the size and the speed. Add that vector the the particle&#8217;s position.<br />
In the <em>PerFrameControl</em> event, we add:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">pos <span style="color: #339933;">=</span> inParticle.<span style="color: #660066;">Position</span><span style="color: #339933;">;</span>
wobble <span style="color: #339933;">=</span> XSIMath.<span style="color: #660066;">CreateVector3</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">0.5</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> size <span style="color: #339933;">*</span> speed.<span style="color: #660066;">Length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">0.5</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> size <span style="color: #339933;">*</span> speed.<span style="color: #660066;">Length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
pos.<span style="color: #660066;">AddInplace</span><span style="color: #009900;">&#40;</span>wobble<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
inParticle.<span style="color: #660066;">Position</span> <span style="color: #339933;">=</span> pos<span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>The big particles will wobble more than the small ones, and all particles will wobble progressively more as they gain speed.</p>
<p><strong>The Sprite Sequence Problem.</strong><br />
We have a sequence of images of a bubble rising to the surface to apply on the sprite shader of the particles. It is 100 frames long. There are many choices for the behavior of the sprite sequence on the particles, but an important one is missing. We want each particle to choose a random frame in the sequence at its birth, and take the next frame of that sequence at each frame it ages. For this, we need to create a new User Parameter on the PType. We name it &#8220;BeginSpriteSeq&#8221; and set its type to Integer.</p>
<p>We set this parameter to a random value between 0 and 100, the length of the sequence, on each particle. In the <em>BirthControl</em> event, we add the following line:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">inParticle.<span style="color: #660066;">Attributes</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;BeginSpriteSeq&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">Value</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Then, we need to tell the particle to choose the next frames over time. In the <em>PerFrameControl</em> event, we add the line:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">inParticle.<span style="color: #660066;">SpriteIndex</span> <span style="color: #339933;">=</span> inParticle.<span style="color: #660066;">Attributes</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;BeginSpriteSeq&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">Value</span> <span style="color: #339933;">+</span> inParticle.<span style="color: #660066;">Age</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>I know there are ways to fake this in the render tree but the pseudo-random value is not very easy to obtain and it makes a recipe that is more complicated to update from one situation to another. However, contrary to the scripted event solution, it does not increase the simulation time.</p>
<p><strong>The Result.</strong><br />
After all the work, we end up with only two events that solve all the problems encountered with a reasonable simulation time.</p>
<p><em>BirthControl</em> event<br />
trigger: Particle Age = 0<br />
ScriptContext: Per Trigger Particle</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">inParticle.<span style="color: #660066;">Size</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">pow</span><span style="color: #009900;">&#40;</span> Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">5</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">0.025</span> <span style="color: #339933;">+</span> <span style="color: #CC0000;">0.005</span><span style="color: #339933;">;</span>
inParticle.<span style="color: #660066;">Attributes</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;BeginSpriteSeq&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">Value</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><em>PerFrameControl</em> event<br />
trigger: Every N Frame = 1<br />
ScriptContext: Per Particle</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">//speed control</span>
speed <span style="color: #339933;">=</span> inParticle.<span style="color: #660066;">Velocity</span><span style="color: #339933;">;</span>
size <span style="color: #339933;">=</span> inParticle.<span style="color: #660066;">Size</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>speed.<span style="color: #660066;">Length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> size <span style="color: #339933;">*</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>  <span style="color: #006600; font-style: italic;">// if speed is bigger than 10 times the size...</span>
    speed.<span style="color: #660066;">NormalizeInPlace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>      <span style="color: #006600; font-style: italic;">// scale the speed to be 1 and</span>
    speed.<span style="color: #660066;">ScaleInPlace</span><span style="color: #009900;">&#40;</span>size <span style="color: #339933;">*</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// scale speed to be 10 times the size.</span>
<span style="color: #009900;">&#125;</span>
inParticle.<span style="color: #660066;">Velocity</span> <span style="color: #339933;">=</span> speed<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//wobble</span>
pos <span style="color: #339933;">=</span> inParticle.<span style="color: #660066;">Position</span><span style="color: #339933;">;</span>
wobble <span style="color: #339933;">=</span> XSIMath.<span style="color: #660066;">CreateVector3</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">0.5</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> size <span style="color: #339933;">*</span> speed.<span style="color: #660066;">Length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">0.5</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> size <span style="color: #339933;">*</span> speed.<span style="color: #660066;">Length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
pos.<span style="color: #660066;">AddInplace</span><span style="color: #009900;">&#40;</span>wobble<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
inParticle.<span style="color: #660066;">Position</span> <span style="color: #339933;">=</span> pos<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">//sprite sequence</span>
inParticle.<span style="color: #660066;">SpriteIndex</span> <span style="color: #339933;">=</span> inParticle.<span style="color: #660066;">Attributes</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;BeginSpriteSeq&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">Value</span> <span style="color: #339933;">+</span> inParticle.<span style="color: #660066;">Age</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Here is a <a href="/userContent/upload/TricksParticleEvents.zip" title="">Quicktime movie</a> of the result.<br />
Here is a <a href="/userContent/upload/TricksParticleEvents_Crop.zip" title="">close-up</a> from the HD version.</p>
<p>In the final version of this recipe, I had to change the script context of the events because I wanted to add a custom PPG on the cloud with some parameters to control the various effects. This required a Dictionary.GetObject() to get the values of those parameters in each event and I didn&#8217;t want to evaluate it for each particle. I set the script contexts to Per Cloud, and did some conditional expressions to replace the triggers.</p>
<p>I&#8217;m glad we can solve these problems since they occur surprisingly often in production. However, I wish the solutions were more accessible from the UI. Not only would it make it easier for an artist to use them, but also the simulation times might be decreased since it would be part of the internal solver. I hope the good people at Softimage consider those problems in the new particle system they are preparing. The ability to customize the distribution of random values on a parameter is essential to a good simulation package. So is the ability to link random values from one parameter to another.</p>
<img src="http://www.softimageblog.com/?ak_action=api_record_view&id=127&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.softimageblog.com/archives/127/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Enveloping rigid elements</title>
		<link>http://www.softimageblog.com/archives/110#utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=enveloping-rigid-elements</link>
		<comments>http://www.softimageblog.com/archives/110#comments</comments>
		<pubDate>Mon, 21 Aug 2006 10:15:24 +0000</pubDate>
		<dc:creator>Helge Mathee</dc:creator>
				<category><![CDATA[JScript]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Rigging]]></category>

		<guid isPermaLink="false">http://www.xsi-blog.com/?p=110</guid>
		<description><![CDATA[how to get elements on a surface, while they are not deforming.]]></description>
			<content:encoded><![CDATA[<p>Alright, here&#8217;s a new article of mine. This time I am dealing with a problem a lot of people are facing when trying to envelope a large number of objects onto a surface, while the objects themselves are not supposed to deform. As this is a typical problem related to objects like feathers, all scripts + tools are named somewhat related to feathers. All of these techniques can be applied to other objects as well, though.</p>
<p>Lets start. One easy way to approach this problem is to create a mesh including all objects we want to envelope, and then simply set the envelope weights of all points of a single instance to the exact same weight, aka:</p>
<p>In this image we have a mesh with 6 cubes (all merged together) enveloped to a two-bone chain.<br />
By default the weight is blended in the middle part,</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_01.jpg" alt="" /></p>
<p>which results in a deform for the middle two cubes:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_02.jpg" alt="" /></p>
<p><span id="more-110"></span>by using the weight editor, I adjusted the weight of all cubes so they only target one bone:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_03.jpg" alt="" /></p>
<p>which results in movement, but not deformation for each one:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_04.jpg" alt="" /></p>
<p>So this is all working, why bother dealing with a system to deal with these things? Well, as long as we are dealing with six cubes it is all cheesy and simple, but as soon as we start dealing with something like feathers on a bird, we can&#8217;t just go in and envelope each feather with the weight editor, well, we could, but it would just take forever.</p>
<p>What I used to do in those cases is to build an instancer operator, which would take a mesh containing &#8220;where-and-how-to-instance&#8221; information, and a single mesh which is supposed to be instanced. First, lets clarify the &#8220;where&#8230;to-instance&#8221; part:</p>
<p>When instancing an object, all you need is a position, orientation and scaling, which can be stored as three points really, but in this example I am going to use 4 points:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_05.jpg" alt="" /></p>
<p>1. Pos: The position of the object to be instanced<br />
2. Cns: The Z-Direction of the object (seen from pos)<br />
3. Upv: The Y-Direction of the object (seen from pos)<br />
4. Bnd: An additional point to be used for deformation (later)</p>
<p>So basically we could draw a quadrangular polygon instead of four points, like below, where we are instancing ten grids:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_06.jpg" alt="" /></p>
<p>Now: Instead of enveloping the objects we want to be instanced, we envelope the mesh containing the quads. This is going to be called our &#8220;Instancing-Cloud&#8221;. It contains all of the information we need to instance our objects. Moreover, it is easy to envelope, as we know exactly which points are to be enveloped where. Every first out of four points is the position, every second out of four points is the z-direction etc&#8230; All we need to build is a couple of scripts:</p>
<p>1. One which adds a quadrangle to a mesh based on a transform of a null.<br />
2. One which creates a new mesh and instances an object onto an Instancing-Cloud.<br />
3. One which generates clusters for the instance-cloud for easier enveloping.</p>
<p>A finished setup could look something like this: We see the quads representing the instances:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_07.jpg" alt="" /></p>
<p>When deformed: The quads deform, but the instances will not:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_08.jpg" alt="" /></p>
<p>Including the instances it should look like this:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_09.jpg" alt="" /></p>
<p>When deformed:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_10.jpg" alt="" /></p>
<p>As we have point clusters for each type of point in the instance-cloud (pos, cns, upv and bnd) it is quite simple to rig the cns for example to a bunch of rotational controllers:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_11.jpg" alt="" /></p>
<p>And when we rotate them, only the cns points are deformed, therefore the instances rotate as well:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_12.jpg" alt="" /></p>
<p>Additionally we can deform the cloud overall:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_13.jpg" alt="" /></p>
<p>So now lets discuss the last part of the story: What&#8217;s the bnd position for?<br />
The bnd position is used for deformation of each instance. As this is quite limited, all I am going to do is move the instances points using a sinus function, to get somewhat of twisting and bending going on. This is up to your imagination, as I said, this setup has been used for feathers, that&#8217;s why the bnd position is used for bending (and named like that as well: bnd = bending).</p>
<p>In the next image I rigged the bnd position to the rotational controller earlier used for cns, to show what happens:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_11.jpg" alt="" /></p>
<p>So now when I rotate them:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_14.jpg" alt="" /></p>
<p>Or along another axis:</p>
<p><img src="http://www.xsi-blog.com/userContent/hmathee/wingRig/rigid_env_15.jpg" alt="" /></p>
<p>As always &#8211; <a href="http://www.xsi-blog.com/userContent/hmathee/wingRig/mt_feathers.js">I&#8217;d like to share the progress so far</a>, but I have to warn you, it is not at all documented:</p>
<p>Put the file into one of the plugins folders, and run the following script to get some feather setup going:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">NewScene<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> cloud <span style="color: #339933;">=</span> mt_createFeatherCloud<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> grid <span style="color: #339933;">=</span> CreatePrim<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Grid&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;MeshSurface&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
SetValue<span style="color: #009900;">&#40;</span>grid<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;.grid.ulength&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0.4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
SetValue<span style="color: #009900;">&#40;</span>grid<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;.grid.vlength&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
SetValue<span style="color: #009900;">&#40;</span>grid<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;.polymsh.geom.subdivu&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Translate<span style="color: #009900;">&#40;</span>grid<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;.pnt[*]&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1.4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> siRelative<span style="color: #339933;">,</span> siLocal<span style="color: #339933;">,</span> siObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
FreezeObj<span style="color: #009900;">&#40;</span>grid<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> mesh <span style="color: #339933;">=</span> mt_createFeatherMesh<span style="color: #009900;">&#40;</span>cloud<span style="color: #339933;">,</span> grid<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> feathers <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> ActiveXObject<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;XSI.Collection&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span><span style="color: #CC0000;">10</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
feathers.<span style="color: #660066;">Add</span><span style="color: #009900;">&#40;</span>mt_createFeatherNull<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
feathers<span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">kinematics</span>.<span style="color: #660066;">local</span>.<span style="color: #660066;">posx</span>.<span style="color: #660066;">value</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
mt_addFeathersToCloud<span style="color: #009900;">&#40;</span>cloud<span style="color: #339933;">,</span>feathers<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
mt_createCloudClusters<span style="color: #009900;">&#40;</span>cloud<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
DeselectAll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Let me know how it goes,</p>
<p>enjoy!</p>
<img src="http://www.softimageblog.com/?ak_action=api_record_view&id=110&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.softimageblog.com/archives/110/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Soft IK in XSI, Part II &#8211; Stretchy bones</title>
		<link>http://www.softimageblog.com/archives/109#utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=soft-ik-in-xsi-part-ii-stretchy-bones</link>
		<comments>http://www.softimageblog.com/archives/109#comments</comments>
		<pubDate>Wed, 16 Aug 2006 17:28:06 +0000</pubDate>
		<dc:creator>Andy Nicholas</dc:creator>
				<category><![CDATA[Animation]]></category>
		<category><![CDATA[JScript]]></category>
		<category><![CDATA[Programming / Scripting]]></category>
		<category><![CDATA[Rigging]]></category>

		<guid isPermaLink="false">http://www.xsi-blog.com/?p=109</guid>
		<description><![CDATA[When I wrote the first article, I hadn&#8217;t planned on writing a sequel, but a couple of people on XSIBase asked me to look into how I could extend the Soft IK system to work with a stretchy bone chain. 
Initially, figuring out how this could work seems like a pretty tricky problem. The bone [...]]]></description>
			<content:encoded><![CDATA[<p>When I wrote the first article, I hadn&#8217;t planned on writing a sequel, but a couple of people on XSIBase asked me to look into how I could extend the Soft IK system to work with a <em>stretchy</em> bone chain. </p>
<p>Initially, figuring out how this could work seems like a pretty tricky problem. The bone chain needs to stretch intuitively to give the impression that it&#8217;s stuck to the IK effector. But we also need it to flatten gradually to avoid the snap effect. Unfortunately, the only thing we have available to us to control these two effects, is the ability to change the length of the bones, since the end position of the chain must always be located at the effector. </p>
<p>So we need to scale the bones to allow them to stretch, but at a specific rate to make sure we avoid the snap. Like this:</p>
<p><img src="/userContent/anicholas/softik/StretchyChain.gif" alt="Stretchy Soft IK" /></p>
<p><span id="more-109"></span>The first thing to do is to look at how we solved the problem for the non-stretchy bone chain. When we look at what happens when we move the Soft Effector past the point where it starts to leave the original IK effector behind, all we want to do for the stretchy bone chain system is make sure that the bone chain gets longer so that the original IK effector is at the same position as the Soft Effector. But we need to do this while also keeping the bones angles the same, this avoids the snap effect since the bone angles would change at exactly the same rate as in the non-stretchy bone chain system.</p>
<p>A diagram should make things a bit clearer. Basically, given a non-stretchy chain, we want to match the position of the two effectors by scaling the chain length, but without changing the bone angles, like this:</p>
<p><img src="/userContent/anicholas/softik/ChainScale.gif" alt="Scaling the Soft IK chain" /></p>
<p>Okay, so that doesn&#8217;t seem too hard. We just need to figure out how much to move the IK Effector to match the position of the soft effector. </p>
<p>The only way we can do this is by changing the length of the bone chain. Again, this initially looks like quite a tricky problem, until you realize that scaling the length of each bone by some value X, also scales the distance of the original IK effector from the IK root by a factor of X as well. A simple test proves it (and it can be easily shown with a little math too):</p>
<p><img src="/userContent/anicholas/softik/ScaleChain.gif" alt="Scaling bone lengths" /></p>
<p>This diagram shows a bone chain with bones of different lengths, before and after I scaled each individual bone length by a factor of 2. It can be seen that the IK effector has traveled directly away from the IK root and has doubled it&#8217;s distance from it. Not only that, but the bone angles have remained unchanged. This is exactly what we need!</p>
<p>Now, all we need to do is to figure out the amount we need to scale each bone length to make the original IK effector match the position of the soft effector. That scale factor is just the ratio of the distances of the two effectors:</p>
<p><em>Scale Factor = EvalDistance(IK root, Soft Effector) / EvalDistance(IK root, original IK effector)</em></p>
<p>Where EvalDistance() is just a function that measure the distance between the two objects.</p>
<p>Finally, we need to position constrain the original IK effector to the soft effector, so that it follows it. Otherwise, all that would happen is that the length of the chain would change.</p>
<p>So that&#8217;s it, we&#8217;re there. All that remains is to package it all up into a plugin with a handy custom property to drive it all. This is what the new property page looks like:</p>
<p><img src="/userContent/anicholas/softik/StretchyPPG.gif" alt="Stretchy Soft IK PPG" /></p>
<p>The bone lengths can be adjusted (and even animated) from this PPG, as well as the Soft Distance parameter, which behaves in exactly the same way as in the non-stretchy Soft IK. The bone lengths are all driven from this PPG using expressions. Note, that for extra performance we only have one Scripted Operator here which operates on the BoneScale parameter of the PPG. </p>
<p> I&#8217;ve updated the original Soft Effector script to include a new menu item to apply the Stretchy Bone Soft IK system to any chain you select.</p>
<p><a href="/userContent/anicholas/softik/FXNut_SoftEffector.zip">Soft Effector Download (3Kb)</a></p>
<p>Incidentally, if you ever want to remove the Soft IK (stretchy or otherwise) from a bone chain. All you have to do is delete the Soft Effector object. All the expressions and operators will be automatically deleted since they will have lost their connections. Nice and tidy!</p>
<p>P.S. Thanks to Daniele Niero for suggesting I cache the math objects inside the operator user data!</p>
<img src="http://www.softimageblog.com/?ak_action=api_record_view&id=109&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.softimageblog.com/archives/109/feed</wfw:commentRss>
		<slash:comments>46</slash:comments>
		</item>
		<item>
		<title>Soft IK in XSI</title>
		<link>http://www.softimageblog.com/archives/108#utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=soft-ik-in-xsi</link>
		<comments>http://www.softimageblog.com/archives/108#comments</comments>
		<pubDate>Mon, 14 Aug 2006 12:48:12 +0000</pubDate>
		<dc:creator>Andy Nicholas</dc:creator>
				<category><![CDATA[Animation]]></category>
		<category><![CDATA[JScript]]></category>
		<category><![CDATA[Programming / Scripting]]></category>
		<category><![CDATA[Rigging]]></category>

		<guid isPermaLink="false">http://www.xsi-blog.com/?p=108</guid>
		<description><![CDATA[When an IK chain extends towards its full length, it will tend to snap into it&#8217;s final position. To prevent this from happening, it is possible to give the appearance that the IK chain is stiffening as it extends towards it&#8217;s full length. This technique isn&#8217;t new and similar functionality is already implemented in Cinema [...]]]></description>
			<content:encoded><![CDATA[<p>When an IK chain extends towards its full length, it will tend to snap into it&#8217;s final position. To prevent this from happening, it is possible to give the appearance that the IK chain is stiffening as it extends towards it&#8217;s full length. This technique isn&#8217;t new and similar functionality is already implemented in Cinema 4D.</p>
<p>In XSI, we need a way of allowing the chain to gradually fall behind the position of the effector. This stops the effector from snapping the chain into the final position, and gives rise to a much more natural motion (as seen below).</p>
<p><img src="/userContent/anicholas/softik/SoftIK.gif" alt="Soft IK Comparison" /><br />
<em>(Note: If you are unable to view the GIF animation, you may need to change settings in your Firewall. For example, in Zone Alarm, you need to disable Privacy->Ad Blocking)</em></p>
<p><span id="more-108"></span>The snap effect visible in the top chain isn&#8217;t due to some inaccuracy in the IK calculation, but is just down to a simple geometrical effect. It can be shown mathematically (see diagram below) that as the effector pulls the chain into the final position, the velocity of the bones towards their final position tends towards infinity! This is obviously not desirable and can make the animation look jerky and artificial.<br />
<a href="/userContent/anicholas/softik/BoneSnap.gif" target="_blank"><br />
<img src="/userContent/anicholas/softik/BoneSnap_thumb.gif" alt="Why snapping happens" /></a><br />
<em>(click to enlarge)</em></p>
<p>To achieve the type of motion shown in the lower chain, we need to add an extra object which is used to drive the IK chain effector. A scripted operator links the two objects and we use a mathematical expression to give the desired result. The only bits of information the operator needs are the total chain length, and something I call the &#8220;Soft Distance&#8221;. This represents the distance from the chain&#8217;s full extension that the effect starts to work.</p>
<p>There is one downside with this approach, as it means you can&#8217;t fix the end point of the chain in position. However, this can be solved as long as you are willing to put a small amount of extra work to animate the Soft Distance parameter.</p>
<p>The soft effector object has a custom property to allow you to easily control the operator.</p>
<p><img src="/userContent/anicholas/softik/PPG.gif" alt="Soft Effector PPG" /></p>
<p>To make things easier for you, the Chain Length is calculated by an expression which sums the length of each bone in the chain. This allows you to change the length of a bone, and still have the Soft IK work.</p>
<p>In the diagram below, the Soft Distance is represented by the distance between the green and the red lines (actually, they&#8217;re circles, but too large to see). As soon as the effector reaches the green line, our scripted operator starts to lag the chain effector behind our soft effector. This is done while making sure that we have no jerkiness in the motion of the chain effector.</p>
<p><img src="/userContent/anicholas/softik/SoftIK_Closeup.gif" alt="Soft IK Closeup" /><br />
<em>(Note: If you are unable to view the GIF animation, you may need to change settings in your Firewall. For example, in Zone Alarm, you need to disable Privacy->Ad Blocking)</em></p>
<p>The equation used to create this effect is shown below:</p>
<p><a href="/userContent/anicholas/softik/Equation.gif" target="_blank"><br />
<img src="/userContent/anicholas/softik/Equation_thumb.gif" alt="Soft Effector Equation" /></a><br />
<em>(click to enlarge)</em></p>
<p>For a chain length of 3 and a soft distance of 1, this equation looks something like this:</p>
<p><a href="/userContent/anicholas/softik/MainGraph.gif" target="_blank"><img src="/userContent/anicholas/softik/MainGraph_thumb.gif" alt="Distance Graph" /></a><br />
<em>(click to enlarge)</em></p>
<p>You can use the following link to download the Soft Effector plugin:</p>
<p><a href="/userContent/anicholas/softik/FXNut_SoftEffector.zip">Soft Effector Download (3 Kb)</a></p>
<p>(Note that this also features the Stretchy Bone Chain extension shown in <a href="/archives/109">Part 2</a> of this article)</p>
<p>To install the plugin, just download the zip file, unzip the script, and copy it to a &#8220;Plugins&#8221; folder. So for example, you can use your &#8220;C:\users\<em>username</em>\Softimage\XSI\Application\Plugins&#8221; folder, or one in your workgroup. </p>
<p>To use the Soft Effector, create a 2D or 3D Skeleton Chain, select any part of the chain, and go to &#8220;Model->Create->Skeleton->Apply Soft Effector&#8221;.</p>
<img src="http://www.softimageblog.com/?ak_action=api_record_view&id=108&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.softimageblog.com/archives/108/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>
