tag:blogger.com,1999:blog-40379543504649980262024-02-20T15:46:58.969-08:00Julian Johnson's BlogJulian Johnsonhttp://www.blogger.com/profile/16815800526239684276noreply@blogger.comBlogger34125tag:blogger.com,1999:blog-4037954350464998026.post-31716668507825971012019-05-10T22:22:00.001-07:002019-05-10T22:24:18.886-07:00Liang–Barsky Line Clipping And Why You Need Not Bother<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh80gT_H_I70W0KBvDueAMf3rm8ycvNx2DDOzInf-fUE02_RgNLZD8rJRAlMVkSuGSLjKzKHfUxbfoOdo2IU6PhUfKLDwg69qH9Fus1cabnU3HPYhKERR2lhaYMOIrjE-ijjy16FO2epwE/s1600/clipping.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="460" data-original-width="603" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh80gT_H_I70W0KBvDueAMf3rm8ycvNx2DDOzInf-fUE02_RgNLZD8rJRAlMVkSuGSLjKzKHfUxbfoOdo2IU6PhUfKLDwg69qH9Fus1cabnU3HPYhKERR2lhaYMOIrjE-ijjy16FO2epwE/s1600/clipping.gif" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
I spent numerous hours working out how to efficiently clip strands/polylines in VEX for a project with dense strand meshes. I thought I'd been really clever implementing the <a href="https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm">Liang-Barsky</a> algorithm on the NDC cube and then I stumbled into the problem of how to interpolate all existing attributes at the intersection points. Asking for help on various forums - Matt Estela pointed out that the same effect could be achieved with four Clip SOPs in NDC space with the additional bonus of 'free' attribute interpolation. I can't bear the thought of all that time going to waste so here is a vex implementation of Liang-Barsky - maybe someone can find some kind of use for it!<br />
<br />
File is <a href="https://www.dropbox.com/s/z2lemly7mtydban/liang_barsky.rar?dl=0">here</a>. Julian Johnsonhttp://www.blogger.com/profile/16815800526239684276noreply@blogger.com0tag:blogger.com,1999:blog-4037954350464998026.post-65523115356263480282019-05-06T01:00:00.003-07:002019-05-06T02:03:50.473-07:00Cantor Pairing For Impact Data And Generating Dynamic Bullet Constraints<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVNvdubR8_o0duQn5bFSwrOnSen39U2sd3-JsPXO7XzZWICsQH2P9Xy5Xgmt0ldts55_bH-MB_uecSc4h6BegASfCO3OX6YANlZIQ3ebkx_voNT0ex__pMpuprfQrwgaBb6lrK1qfsThA/s1600/cantor.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="460" data-original-width="603" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVNvdubR8_o0duQn5bFSwrOnSen39U2sd3-JsPXO7XzZWICsQH2P9Xy5Xgmt0ldts55_bH-MB_uecSc4h6BegASfCO3OX6YANlZIQ3ebkx_voNT0ex__pMpuprfQrwgaBb6lrK1qfsThA/s1600/cantor.gif" /></a></div>
<br />
<br />
<br />
<br />
<br />
There have been some fantastic resources for demonstrating how to create dynamic constraints in Bullet - most notably Rich Lord's <a href="https://www.richlord.com/">stuff</a> and, as usual, examples on Matt Estela's <a href="http://www.tokeru.com/cgwiki/index.php?title=ConstraintNetworks">site.</a><br />
<br />
The process, however, of establishing which collisions took place between which objects can be quite tricky and intensive - particularly as the Impact Data which records this stuff contains many duplicates of impacts between the same objects across multiple substeps. Usually you'd use a few For Loops to rationalise and structure this data.<br />
<br />
The scene below uses a simple pairing formula called <a href="https://en.wikipedia.org/wiki/Pairing_function">Cantor Pairing</a> to essentially encode a collision between a pair of objects into a single number - it's then very easy to see if that collision has happened before and/or to remove duplicates of that collision. It also seems to be quite fast.<br />
<br />
The sample scene does that encoding and then establishes constraints dynamically at impact points. I think (hope) it's as simple as it can get but, as always with Houdini, there are probably better ways.<br />
<br />
<a href="https://www.dropbox.com/s/mrylojnhd9fr3ue/cantor_pairing.rar?dl=0">hipfile</a>.Julian Johnsonhttp://www.blogger.com/profile/16815800526239684276noreply@blogger.com0tag:blogger.com,1999:blog-4037954350464998026.post-8464490941406790772019-05-05T23:31:00.003-07:002019-05-05T23:31:35.147-07:00Weighted Average of Quaternions Without Flipping?<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYvUqXk43sp1ROOr5TErk1hxBmBL5EBnXqEcXHNdvUI16_Cj1FqyPkDUkyAmiUZPUXRd2GbfQ2-URsiZN3mTS4k2uu1hZQPOiIFgZpTroQcHJUItzavDDGeGuP7ZVBW08dY1ew_-AK8zU/s1600/nasa.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="460" data-original-width="603" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYvUqXk43sp1ROOr5TErk1hxBmBL5EBnXqEcXHNdvUI16_Cj1FqyPkDUkyAmiUZPUXRd2GbfQ2-URsiZN3mTS4k2uu1hZQPOiIFgZpTroQcHJUItzavDDGeGuP7ZVBW08dY1ew_-AK8zU/s1600/nasa.gif" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br /><br />
<br />
<br />
If you look around the Internet for the best mechanism to create an average quaternion, and particularly a weighted average of multiple quaternions you will almost always end up at this pdf from <a href="https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20070017872.pdf">NASA</a>.<br />
<br />
A simpler way of averaging quaternions is possibly just to sequentially lerp or slerp between pairs of quaternions and adjust the weights at each step but this may or may not be accurate depending on the order in which you select the pairs. There's some debate on the best way to do this.<br />
<br />
An additional problem with simply lerping quaternions is that they have a “double-cover” property, where there are two different quaternions (negatives of each other) that represent the same 3D rotation. Normal lerp between them is dependent on which of those 'doubles' the quaternion actually is - you can go the long way round or the short way round. Looking at the orientation in the viewport you have no idea which one is being used. If, say, you have two similar quaternions but one is using something close to the negative of the other you can get very fast rotations around 180 degrees which look like flips. Slerp solves this problem but only between pairs (as well as providing a constant velocity as the interpolant increases which normal lerp doesn't).<br />
<br />
When you use primuv to interpolate quaternions across a polygon in Houdini, that interpolation is a simple lerp between the numbers in the quaternions - you cannot guarantee that the blend will take the shortest arc (in which case you'll get strange intermediate rotations).<br />
<br />
I found some Python code for implementing the NASA paper and made a scene to compare and contrast the different types of interpolation. The NASA results do look way better than naive primuv-style lerp. But, since it's python/numpy it's not that fast.<br />
<br />
File is <a href="https://www.dropbox.com/s/k57e34uwiml6zrc/quatinterpolate.rar?dl=0">here</a>.Julian Johnsonhttp://www.blogger.com/profile/16815800526239684276noreply@blogger.com0tag:blogger.com,1999:blog-4037954350464998026.post-2672399100873492072017-11-25T08:38:00.001-08:002017-11-25T08:38:56.275-08:00Odds And Ends 02<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUIgPk1iygf5MkvpjhSTP4KyvyT-hOcSSyHkyCI6hhUeRnfG_oxQf-lE-u3nOMuyyg9eLaoGfSFh8OJ8rmtbtgoF3Fi1Gws06Km2Y6svJPBy07dVF3uGZ-l6B1XcZvtPgzfoFSr7wYKPY/s1600/parentcube.gif.1d5e6894afe5cd4731990e87150c9a35.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="460" data-original-width="603" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUIgPk1iygf5MkvpjhSTP4KyvyT-hOcSSyHkyCI6hhUeRnfG_oxQf-lE-u3nOMuyyg9eLaoGfSFh8OJ8rmtbtgoF3Fi1Gws06Km2Y6svJPBy07dVF3uGZ-l6B1XcZvtPgzfoFSr7wYKPY/s1600/parentcube.gif.1d5e6894afe5cd4731990e87150c9a35.gif" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
This is a vex-driven cube fold/unfold using a hierarchy of matrices in a parent/child relationship. Crazily useless!<br />
<br />
<a href="https://www.dropbox.com/s/65zxr60ib5s9ihu/parenting_cube_example.rar?dl=0">hipnc file</a>Julian Johnsonhttp://www.blogger.com/profile/16815800526239684276noreply@blogger.com0tag:blogger.com,1999:blog-4037954350464998026.post-87223427665960420882017-11-25T08:33:00.000-08:002017-11-25T08:48:19.831-08:00Odds And Ends 01<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFJGTL0ZzCK32B1vi2A9IxSVkTku40YJHJzKU6S1F6WnPLL3lTf4QibFRE7oZCvYF9h3F8hAvDlN5mSKnSYYq2q2C3Mc31BSPMmqLaLlV-iGk3Wa0U1O_KRR8rKzlSVVnfAOM7tMVsOyA/s1600/rbd.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="460" data-original-width="603" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFJGTL0ZzCK32B1vi2A9IxSVkTku40YJHJzKU6S1F6WnPLL3lTf4QibFRE7oZCvYF9h3F8hAvDlN5mSKnSYYq2q2C3Mc31BSPMmqLaLlV-iGk3Wa0U1O_KRR8rKzlSVVnfAOM7tMVsOyA/s1600/rbd.gif" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
I thought I would collate together some of the scenes I've been experimenting on and posting on forums - more for my own reference than anything else!<br />
<br />
The first is based on an ICE setup for grooming feathers that Psyop demoed a few years ago. It establishes a local reference frame on each point and then interpolates between multiple guide nulls to orient 'feathers' relative to that local orientation. I was hoping to use the new array slerp vex function introduced in 16.0/16.5 but I couldn't get predictable results from it so reverted back to a rough and ready 'piecewise' quaternion slerp to get a weighted average. I am absolutely positive there are much simpler ways in Houdini to achieve the same effect!<br />
<br />
<a href="https://www.dropbox.com/s/uxaj597a56vd4ux/quaternion%20guides.rar?dl=0">hipnc file</a><br />
<br />
<br />Julian Johnsonhttp://www.blogger.com/profile/16815800526239684276noreply@blogger.com0tag:blogger.com,1999:blog-4037954350464998026.post-69235173454654055642017-06-10T01:34:00.000-07:002017-06-10T01:38:10.792-07:00Smoother Reference Frames on Curves<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1T29y5ULQN74M9X-HubU_4vEQU89ALMxEjD_e4FXHhVNQvkCFYxkFrGyRfwRsUnb3KXpSMDJqikRtNHR0laRRNK0nXQH6SrJ1yoFEpS5mcRd4eiE628ilf4_YKy2Bs4-MNt1RkwrYNHg/s1600/parallel_transport.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="287" data-original-width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1T29y5ULQN74M9X-HubU_4vEQU89ALMxEjD_e4FXHhVNQvkCFYxkFrGyRfwRsUnb3KXpSMDJqikRtNHR0laRRNK0nXQH6SrJ1yoFEpS5mcRd4eiE628ilf4_YKy2Bs4-MNt1RkwrYNHg/s1600/parallel_transport.gif" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
I used this <a href="https://pdfs.semanticscholar.org/7e65/2313c1f8183a0f43acce58ae8d8caf370a6b.pdf">paper </a>on Parallel Transport Reference Frames and some great advice from <a href="http://www.andynicholas.com/">Andy Nicholas</a> (who did a better version in a tenth of the time!) to make a tool to construct smooth reference frames on curves with twist and rotation. Hipfile (NC) is <a href="https://www.dropbox.com/s/aplxm5whw3qoi28/Parallel_blog.rar?dl=0">here</a>.Julian Johnsonhttp://www.blogger.com/profile/16815800526239684276noreply@blogger.com0tag:blogger.com,1999:blog-4037954350464998026.post-58348205921009837182017-02-20T06:30:00.001-08:002017-02-20T22:13:08.335-08:00Houdini Branching Structures<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij4rp2Vn-JSxxwAZE18JfidUgIOqlXjo-OzW2Sm3SZY37oScRVcQjKLt-RexVxSe19_eCHdH08UTB-qpglpVlPdn_rcwmciiVbZablXco9bOftySyjKPX88oTvlIODVNVDqvc0Tvwl0ZU/s1600/hbranch.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij4rp2Vn-JSxxwAZE18JfidUgIOqlXjo-OzW2Sm3SZY37oScRVcQjKLt-RexVxSe19_eCHdH08UTB-qpglpVlPdn_rcwmciiVbZablXco9bOftySyjKPX88oTvlIODVNVDqvc0Tvwl0ZU/s1600/hbranch.jpg" /></a><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
First attempt to do some branching in Houdini. Nothing new really. There's a silent walk through of the main controls on Vimeo <a href="https://vimeo.com/204776658" target="_blank">here</a>. It's based on some of the concepts in Fabricio Chamon's brilliant <a href="http://iceduous.blogspot.co.uk/2010/04/strandtree-procedural-approach-to-tree.html" target="_blank">Strand Tree ICE</a> compound. It consists of a simple iterative paradigm where at each iteration n number of branches are generated and some kind of multiplier is worked into the length, width, angle etc. This multiplier can be attenuated by a 'reduction/increase' factor per iteration or by using a ramp. There are parameters to control the growth and colour with normalised attributes like distance, u etc and these are all left exposed. I hope the video makes it clear. The 'to do' list is massive - proper topologically correct junctions (without hacking it with Fuse or Polygons to VDB) would be great! The full .hip file is <a href="https://www.dropbox.com/s/oivpbcolmuw2muz/branch_v002.rar?dl=0" target="_blank">here</a>. Any tips most welcome - interface or performance enhancements!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4037954350464998026.post-74715192501783299232013-12-30T05:19:00.000-08:002017-03-13T05:34:40.781-07:00Weighted ArraysOften you need to 'weight' the items of an array so that you can achieve a certain ratio e.g for a particle cloud 25% red, 25% blue and 50% green. The archive below contains a couple of sample scenes that show one specific technique (borrowed from Greg Turk's Graphics Gems algorithm for weighting triangles by area) for weighting an array and a couple of compounds kindly made by Dan Yargici making it easy to set up the initial weighted array and then pull data from it. The weighting doesn't have to be normalised - any ratios will work. Download the compounds and scenes <a href="https://www.dropbox.com/s/7crogbym4primdv/weighted_array.rar?dl=0r" target="_blank">here</a>.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4037954350464998026.post-45559091209290246802013-12-30T05:09:00.002-08:002017-03-13T05:36:30.498-07:00Clone With IndexA few months back Graham Fuller posted a <a href="https://groups.google.com/d/msg/xsi_list/4FC1fOFBUHQ/gbthMNGaBG0J" target="_blank">great tip</a> about how to retrieve the clones of a given point on the xsi mailing list. In <a href="https://groups.google.com/d/msg/xsi_list/GhOk3pOnEic/ZW4weRxDXRgJ" target="_blank">this post</a> Gustavo asks how to enumerate the individual clones so you can handle them separately. This<a href="https://www.dropbox.com/s/m1isufii4t1mri3/clone%20with%20index.rar?dl=0" target="_blank"> scene</a> shows three methods - a couple of them use variants of Graham's method whilst one uses a simple loop. They're useful techniques for creating hierarchies of particles where numerous clones can act as 'children' of a master particle.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4037954350464998026.post-7550760411064575702013-07-18T03:00:00.000-07:002017-03-13T05:38:01.805-07:00Faster Polygon Islands<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXw3rEReMZl_kGK6yc6b7FlJOT3OmUGEI_RLEFt5hTIpO1iBMuIz5frV0N_i_8S1DTMAleX-alP21SIL_P1FQge5VU82IneO9EaOMjfJPkLdgCz3irBHT-LwAFX49bhK1Mql05RUuz7Ig/s1600/dog.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXw3rEReMZl_kGK6yc6b7FlJOT3OmUGEI_RLEFt5hTIpO1iBMuIz5frV0N_i_8S1DTMAleX-alP21SIL_P1FQge5VU82IneO9EaOMjfJPkLdgCz3irBHT-LwAFX49bhK1Mql05RUuz7Ig/s1600/dog.png" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Eric Mootz's <a href="http://www.mootzoid.com/wb/pages/softimagexsi/emtools.php" target="_blank">emTools </a>has a suite of compounds to manipulate polygon islands with a particle cloud. They require a pre-calculated index array mapping vertices to their island index. Doing this in ICE directly is relatively slow - quite a bit of work has been done to get these ICE compounds as fast as possible (see Guillaume Laforge's original <a href="http://frenchdog.wordpress.com/2010/03/21/polygon-islands-getting-the-lowest-point-index/" target="_blank">blog post</a> and this <a href="http://www.si-community.com/community/viewtopic.php?f=45&t=2115" target="_blank">thread </a>on si-community.com) but a C++ ice node can usually run orders of magnitude faster. In the case of the node provided here it has proved to be as much as 10-15x faster than the ICE implementations (depending on the scene). I'm sure there's scope for more optimal C++ coding to make it faster still.<br />
<br />
You can use the node to feed data into Eric's vertex island tools (sample scene in the .rar file, remember to install emTools first) or as a standalone utility node if you're manipulating islands in your own way. It takes geometry and point positions as inputs and can output the index array of points and their island index, a per point island index and an array of island centres. It's been compiled against 2013 SP1 64bit. Source code is included with the addon.<br />
<br />
<a href="https://www.dropbox.com/s/6qlcoal28p9p87z/jj_Island_Indexer.1.0.0.rar?dl=0" target="_blank">jj_Island_Indexer 1.0.0 </a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4037954350464998026.post-32112535869265985502013-07-02T09:32:00.002-07:002017-03-13T05:39:15.483-07:00Dart Throw Multiple Size<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-Jg0OnIka-5jntS8qIUg0sqAC8Se5W9M-YvPQsADm3sBYD5vaSKWMUo3Yl2AU4ouLNdjM6noMsyMQgAgwj3Vi2LGW7Zoq-FZZsS18ELrvNi0dehfUy1R9RQ59n2Uv1TE2gwPDpyamDuI/s620/green.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="287" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-Jg0OnIka-5jntS8qIUg0sqAC8Se5W9M-YvPQsADm3sBYD5vaSKWMUo3Yl2AU4ouLNdjM6noMsyMQgAgwj3Vi2LGW7Zoq-FZZsS18ELrvNi0dehfUy1R9RQ59n2Uv1TE2gwPDpyamDuI/s400/green.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Dart Throw has been updated to support an input array of multiple sizes (as well as continuing to support a single input size). You can now instance a group of differently-sized objects onto your
particles by creating an array of the sizes of the objects in the group. Numerous other tweaks and upgrades have been added:<br />
<ul>
<li>Input an array containing multiple sizes and darts will match those sizes</li>
<li>Weight map based size adjustment now supports either absolute or scaled size</li>
<li>Randomising now supports negative variance and either absolute or scaled size</li>
<li>A new 'min size' parameter lets you control/limit the minimum size</li>
<li>Size adjustments via weights and/or randomisations can be applied to the array of input sizes </li>
<li>source code is now included in the src directory of the addon</li>
<li>Illustrative sample scenes are included in the archive</li>
</ul>
The new version of Dart Throw (2013 SP1+, 64bit) can be downloaded <a href="https://www.dropbox.com/s/5f66devkysy3tjo/dart_throw_multisize.v3.0.0.rar?dl=0">here</a>. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh61OdQ0hn0lpCIiCxGuqRdyv_YjszOrVThUx5vm8c-yhnOykYApaLeJ-V7sosDia3ZdCdtSQRojv08-0vvpT_iTl6f1psQY2m_3kqiT5GUuEgha2wioz0AWUbwEr4HMkfrKys3BKxjHGo/s395/panel.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh61OdQ0hn0lpCIiCxGuqRdyv_YjszOrVThUx5vm8c-yhnOykYApaLeJ-V7sosDia3ZdCdtSQRojv08-0vvpT_iTl6f1psQY2m_3kqiT5GUuEgha2wioz0AWUbwEr4HMkfrKys3BKxjHGo/s1600/panel.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ICE Node Inputs</td><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<b>Usage Summary</b><br />
<b><br /></b>
<b><i>Basic</i></b><br />
<i>Iterations</i> <br />
This controls how many attempts are made to position a dart on the geometry. The more attempts you make the denser the packing becomes up to the point where it becomes virtually impossible for a dart to land on an empty space with sufficient room for its size.<br />
<br />
If you look in the history log, Dart Throw reports something like the following: "Max iterations is: 41 at: 49990" (assuming an iterations setting of 50,000). This tells you that the maximum number of attempts it took to get a successful dart inserted was 41 and that happened at iteration 49990.<br />
<br />
In a scenario where you get something like "Max iterations is: 101000 at: 899012" (assuming an iterations setting of 1m) you can see that it's taking over 100,000 attempts just to get one dart positioned. It's probably not worth waiting for that 1 extra dart and so you could reduce your iterations to 899011. In the Misc section you can use an 'Iterations Abort Threshold' parameter to set a value for how many unsuccessful dart throwing attempts the node should make before abandoning automatically. See that section below for detailed instructions.<br />
<br />
<b>Size</b><br />
You can input either an array or a single value here and Dart Throw will generate 'darts' that only use those size(s)<b>.</b> The size array does not need to be in any particular order which means you can put your objects into your instance group any way you see fit.<br />
<br />
<b>Size Adjustment</b><br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVbOLMTkmZPr55YRYrQH9InNbxLN0biyKET3D5yTBF3bE-INjge0d9nmiJvs4AG-bQleomBWdTe6XzhN66Dey8OeCYO0lkVfWTz_UJ_eyf6yeSIxHauWklkvOV0YfFwjWxtQYlmtayCiU/s620/orange.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVbOLMTkmZPr55YRYrQH9InNbxLN0biyKET3D5yTBF3bE-INjge0d9nmiJvs4AG-bQleomBWdTe6XzhN66Dey8OeCYO0lkVfWTz_UJ_eyf6yeSIxHauWklkvOV0YfFwjWxtQYlmtayCiU/s1600/orange.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Two different instance types with sizes adjusted by weightmap.</td></tr>
</tbody></table>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
If you plug a weight map into the size map port you can control the size of your particles using the values in the map as an interpolant. What that means is that the weight map value between 0-1 will interpolate between the Basic::Size parameter you entered above and the Size Adjustment::Adjusted Size parameter you enter in this section.<br />
<br />
The Adjusted Size parameter can be set as either a scaling factor for your size or as an absolute value. Depending on the weight map value your particle size will then interpolate between Size and Adjusted Size.<br />
<br />
<b>Erase</b><br />
If you plug a weightmap into the Erase Map port then darts will only land on areas with a weightmap value on or above the threshold. All other darts will be deleted.<br />
<br />
<b>Randomise</b><br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd8zEqb2C_WjjBqhHbsviz0sRp_1-Up5dvube2JyV7-eKxtnx2DJ4uyUj3QkbJWPtcZQwP_62f2lUvzJ6zWyZn1r-_w9psR1L6X_Blz8sr40uEVLVgHXbyWI8N2cB2OXYTImtBZR6FgUc/s620/blue.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd8zEqb2C_WjjBqhHbsviz0sRp_1-Up5dvube2JyV7-eKxtnx2DJ4uyUj3QkbJWPtcZQwP_62f2lUvzJ6zWyZn1r-_w9psR1L6X_Blz8sr40uEVLVgHXbyWI8N2cB2OXYTImtBZR6FgUc/s1600/blue.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A single instance whose size is randomised using a variance. Version 3 supports negative variance.</td></tr>
</tbody></table>
<br />
The randomise option enables you to add a variance to your sizes either as an absolute value or a scaled value. Randomise assumes a variance around 0 so you'll get both negative and positive variance. This is where setting 'min size' (see below) can help ensure your smallest particles are not pushed into negative territory if you use the scaled option.<br />
<br />
<b>Misc</b><br />
<br />
<i>Iteration Abort Threshold</i><br />
This parameter lets you specify what fraction of the total iterations have to occur without a successful dart before the node automatically stops iterating. For example if you have set 1,000,000 iterations and set this parameter to 0.1 it means that if there are 100,000 iterations without a successful dart the node will stop iterating. <br />
<br />
<i>Min Size</i><br />
Now that the randomise feature (above) supports both absolute and scaled variances it's possible, using scaled, to scale your particles by a negative amount i.e. if your variance is set to, say, 0.5 then you will get scaling values between -0.5 and +0.5. Min Size simply sets a minimum for your particles. (If you use absolute in this scenario it means you can subtract negative values from your particle size which won't necessarily push the size into negative territory).<br />
<br />
<b>Outputs</b><br />
<br />
<i>Position Array</i><br />
This is the array of successful dart positions.<br />
<br />
<i>Size Array/Size Per Point</i><br />
This is the array/per point output of sizes associated with those output positions. Be aware that the size output needs to be treated differently depending on whether you're using intrinsic ice objects like sphere, cube, cone etc. or geometry instances. In the case of intrinsic ice objects you should use this output directly to control the size. In the case of instances you need to divide the output size by the input size to work out a scaling factor for your instances. See the sample scenes for examples.<br />
<br />
<i>Size Index Array/Size Index Per Point</i><br />
If you're using an input array of sizes this is either an array or per point output specifying the index into the input size array for each position. For example, your input size array will match the sequence of sizes in your instance group. When Dart Throw allocates a size to a point you will need to know for each point which size it has selected. This output tells you the index of that size so that you can pick the correct instance from the instance group.<br />
<ul>
</ul>
Unknownnoreply@blogger.com9tag:blogger.com,1999:blog-4037954350464998026.post-41469907731498589182013-06-21T06:33:00.000-07:002017-03-13T05:40:05.682-07:00Texture UV To Location<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7xI3FFRqpQgYWvHaxiMc-HVo7Rede4op1QmTkDJGOjyqO-lIoTOtrIc1nROdz58xmvR3DgVgB9CaFl6BwAeW-eACHSfYPtXpRwFdAaYRpNgP9E-AE4jQ-F1HLItb0hhN3RzwHrsUoyQs/s1600/texture_uv_to_location.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="229" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7xI3FFRqpQgYWvHaxiMc-HVo7Rede4op1QmTkDJGOjyqO-lIoTOtrIc1nROdz58xmvR3DgVgB9CaFl6BwAeW-eACHSfYPtXpRwFdAaYRpNgP9E-AE4jQ-F1HLItb0hhN3RzwHrsUoyQs/s320/texture_uv_to_location.jpg" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
I was motivated by this <a href="https://groups.google.com/forum/?hl=en#!searchin/xsi_list/pointlocators$20in$20ice/xsi_list/rmDmDx9RFm8/VgOId5zY98wJ">thread </a>on the mailing list (and Gustavo's excellent <a href="http://gustavoeb.com.br/mtools">Motion Tools</a>) to work on a C++ ice node to provide a quick way of finding positions from an input texture uv array (the factory-installed UV to Location node doesn't work on polygonal geometry). The method doesn't require triangulated geometry.<br />
<br />
Since we don't have access to pointlocators in the ICE SDK, the node doesn't actually get locations directly but it does generate a position on the polygonal surface from an input UV. The custom ice node is built into a compound that then takes the output positions and generates locations using Get Closest Location. You have the option of using the position directly or using the location port.<br />
<br />
The addon is below for 2013 SP1 (64bit only) and contains C++ source code with comments on the barycentric and triangulation methods as well as notes on some of the problems/choices related to building a custom ice node. A sample scene is also included. If you find a circumstance where it doesn't work correctly I'd be very interested in the scene file.<br />
<i><br /></i>
<i>Updated 28 June 2013</i>:<br />
<i>Crash when no geometry under UV fixed.</i><br />
<a href="https://www.dropbox.com/s/h8a07e2e586aeq5/Texture_To_UV_Location%20v1.1.rar?dl=0">Texture UV To Location v1.1</a>Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-4037954350464998026.post-66367028013702104692013-01-09T09:18:00.000-08:002017-03-13T05:43:13.883-07:00Place Specular Highlights<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI3oRfei926iObFFEvNuW3Wie6ZG2qAzYab5iJl9O05Ov_hL3Dl4aTQf1TA3ICVedRSJlJpGTENR9hVs7X3jJx0csDz3Lkc1TJG8rWRPP640aQIWmoHOAViG944i-uTlvz_KNk9C8T-Ss/s1600/jj_specular_place.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI3oRfei926iObFFEvNuW3Wie6ZG2qAzYab5iJl9O05Ov_hL3Dl4aTQf1TA3ICVedRSJlJpGTENR9hVs7X3jJx0csDz3Lkc1TJG8rWRPP640aQIWmoHOAViG944i-uTlvz_KNk9C8T-Ss/s320/jj_specular_place.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<i>Updated 22nd January.</i> The fifth beta (v0.9b) of a tool using the Custom Tool SDK to interactively place specular highlights on objects is now available. The (updated for v0.9b) movie <a href="https://www.dropbox.com/s/xchie88snmkzvcc/jj_SpecularPlaceTool.mov?dl=0">here</a> shows what the tool can do. <br />
<br />
The tool allows the user to select any pre-existing light, lightroot or object in the scene and that object will be manipulated. If no light or object is selected a spotlight will be created. This means existing VRay and Arnold lights are now supported.<br />
<br />
The main features of v0.9b are now:<br />
<ul>
<li>Place specular highlights from lights directly where you position cursor over an object.</li>
<li>Place any object, not just lights, along the reflection vector.</li>
<li>Place <i>multiple </i>objects simultaneously.</li>
<li>Original distance(s) to incident point is/are retained.</li>
<li>Distance to point can be manipulated with the Shift key.</li>
<li>The cursor can be placed back on the 'specular' point by holding down Shift + CTRL. </li>
</ul>
v0.9b also introduced some significant performance enhancements to the underlying pick routines.<br />
<a name='more'></a>Source is included in the Addon (thanks to Piotrek Marczak, Steve Caron, Reinhard Claus and Ahmidou Lyazidi for their invaluable contributions to this <a href="http://www.si-community.com/community/viewtopic.php?f=16&t=1658">thread </a>on sicommunity).<br />
<br />
The Addon has been compiled against Softimage 2013 SP1 64bit only. The tool can be invoked using the command 'Application.SpecularPlaceTool()' or by using the menu items - Primitive:Light:Specular Place Tool or Transform:Specular Place Tool.<br />
<br />
Version history:<br />
<a href="https://www.dropbox.com/s/rummtc63v3dn3y3/jj_SpecularPlaceTool.v0.9.rar?dl=0">Specular Place Tool v0.9b Addon </a><br />
<br />Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-4037954350464998026.post-43032366026138968802012-12-21T02:53:00.003-08:002017-03-13T05:44:36.489-07:00Convex Hull Using CGAL Library<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNjQyQ1JwgeN_HcBQqi-WSKNHyQ0OhaHhbRxirvLjfqYykYbvteSRFB8O6u9S9ocKjj1GAl6deRfGyEKFmjTgoQ2cRW5d8El2G-SH18fYGctKUvdIWMYhYXJpAMtu6LtxTi4mty8K7GXA/s1600/chull.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNjQyQ1JwgeN_HcBQqi-WSKNHyQ0OhaHhbRxirvLjfqYykYbvteSRFB8O6u9S9ocKjj1GAl6deRfGyEKFmjTgoQ2cRW5d8El2G-SH18fYGctKUvdIWMYhYXJpAMtu6LtxTi4mty8K7GXA/s320/chull.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Although Guillaume Laforge has posted the definitive <a href="http://frenchdog.wordpress.com/2012/01/05/happy-2012/">Convex Hull</a> node for ICE, I thought it would be an interesting exercise to try and hook into the <a href="http://www.cgal.org/">CGAL </a>geometry library and see if it was possible to use their Convex Hull (Qhull) algorithm in an ICE node. It turned out to be relatively straightforward. The Addon and C++ source is <a href="https://www.dropbox.com/s/a8f611zgh4qydl7/jj_Convex_Hull.rar?dl=0">here</a> (2013SP1, 64bit only. Only tested on a couple of machines, let me know if there are any floating dependencies I may have missed). <br />
<br />Unknownnoreply@blogger.com6tag:blogger.com,1999:blog-4037954350464998026.post-91918087127167637482012-11-18T02:51:00.000-08:002017-03-13T05:45:37.459-07:00More Even Spacing<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOtJnhD5uV5awbh2cmRTGDZc5hgyTvHn7sYKU7qxBw0y21n1qiaLHOF6RYaBOMvotrpybTRf0DfgUa9zQ7qdCqKOpo-I8mqC6wTBoRaLzkbNaGo7eKcAr8Qq_6PTfqbpT0sKNQfgmlrdg/s1600/curve.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOtJnhD5uV5awbh2cmRTGDZc5hgyTvHn7sYKU7qxBw0y21n1qiaLHOF6RYaBOMvotrpybTRf0DfgUa9zQ7qdCqKOpo-I8mqC6wTBoRaLzkbNaGo7eKcAr8Qq_6PTfqbpT0sKNQfgmlrdg/s400/curve.gif" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Softimage 2012 gave us the ability to create ICE Attributes directly via scripting and populate them with data. Guillaume Laforge used this ability extensively in CrowdFX and I've recently been using it as a mechanism to easily store large datasets in place of Blobs (e.g. for storing animated curve data from Flame GMasks).<br />
<br />
As a simple example, I created a script which takes an input curve and creates an ICE Attribute on that curve containing evenly-spaced point positions. The relationship is 'live' so you can manipulate the curve and alter the number of evenly spaced 'ICE' points. You could then go on to feed that ICE data into another ICE tree.<br />
<br />
In the same archive I've also included a script to generate a 'real' curve with a live link to the original curve - the new curve has evenly spaced points* and can be any degree you choose and/or constrained to the original. (*This even spacing becomes more accurate the higher your resolution).<br />
<br />
The archive is <a href="https://www.dropbox.com/s/ip3cmjes2w5oaje/jj_even_script_samples.rar?dl=0">here</a>. Unknownnoreply@blogger.com6tag:blogger.com,1999:blog-4037954350464998026.post-39260900431577191932012-11-18T02:15:00.000-08:002017-03-13T05:46:30.405-07:00Using Generate Sample Set to Avoid Repeat LoopsOleg Bliznuk, the author of Exocortex's <a href="http://www.exocortex.com/plugins/implosiafx">Implosia FX</a>, posted a <a href="https://groups.google.com/forum/#!topic/xsi_list/utMwDX74NSY">tip</a> for avoiding repeat loops a few months back using Generate Sample Set.
It's a great tip and one which can generate good time savings over repeat loops. I wanted to test just how much of a saving the tip could provide by calculating a cumulative sum array i.e. given an array of integers, produce another array which gave you the cumulative sum of all elements in the array at any given point.<br />
<br />
The conventional way to do that would be to use a simple repeat loop, but as is always the case with ICE, repeat loops are not necessarily the best way to achieve your desired results as ICE's multithreading isn't optimised in that scenario.<br />
<br />
Oleg's brilliantly lateral idea was to generate a sample for each array member and create an array on that sample the same size as the element's index. You can then populate that array with all the members of your original array up to that point and perform tasks on that segment of the original array.<br />
<br />
I decided to set up a test scene to compare the performance of a conventional repeat loop and Oleg's method. In that test scene, Oleg's method was twice as fast as a repeat loop which is a significant gain.<br />
<br />
But, there is a downside - you pay in RAM usage, sometimes to the point where you might end up paging memory. In my sample scene, the repeat loop method used 200Mb RAM for an array of size 50k whereas in the Generate Sample Set scene RAM usage shot up to nearly 10 Gigabytes! The stepping in terms of RAM usage relative to array size (on my machine) went: 5,000: 373Mb; 10,000: 849Mb; 20,000: 2.6Gig; 30,000: 5.5Gig and so on. It looks like there's a step in RAM usage between 10,000 and 20,000 although I'm guessing this might be machine dependent.<br />
<br />
It's clear that if you're going to use this method in a compound you need to be careful about the maximum array size you're going to allow and possibly switch over to a conventional repeat loop over a certain threshold. <br />
<br />
If you'd like to play with the scene or do your own timings to verify these results it can be downloaded <a href="https://www.dropbox.com/s/cebtmakm9tolzzd/gen_sample_tests.rar?dl=0">here </a>along with the Cumulative Array Sum compound (2013 SP1).Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4037954350464998026.post-17761245387364663562012-01-30T01:46:00.000-08:002017-03-13T05:47:13.315-07:00ICE Modeled Camera Grid<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn1zdgvWaqs6jfwf1NaWj6koMT74qUXP2Z47ekE6bcSiu-0LNCUndDWTKIzGHOLokPe0giY5rZM564uotmp8gNHSQFhB3usr_-BN4spmZAfq3qNGJkK_F1YzX_cQLmCHGJvo2FBNNfzdU/s1600/camplane.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn1zdgvWaqs6jfwf1NaWj6koMT74qUXP2Z47ekE6bcSiu-0LNCUndDWTKIzGHOLokPe0giY5rZM564uotmp8gNHSQFhB3usr_-BN4spmZAfq3qNGJkK_F1YzX_cQLmCHGJvo2FBNNfzdU/s400/camplane.jpg" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
I was way too slow to post this compound to the XSI Mailing list in response to a thread on the creation of a camera plane but here it is anyway! It dynamically creates an ICE modeled grid and places it inside the camera frustum at a specified distance from the camera. At the same time it creates an ICE-based texture projection. Sample scene and compound is <a href="https://www.dropbox.com/s/74h3q037lwg3ndc/camproj.rar?dl=0">here</a>.Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4037954350464998026.post-61580090162340646752012-01-30T01:36:00.000-08:002017-03-13T05:48:22.025-07:00Filtering ArraysStephen Blair has been posting some great articles on the <a href="http://xsisupport.wordpress.com/">eX-SI Support Blog</a> about how to create array patterns i.e ordered sequences like (0,1,2,3,0,1,2,3) or (0,0,0,1,1,1,2,2,2). The creation of this type of sequence can be useful in creating the points of a grid and also for avoiding the use of repeat loops in certain circumstances.<br />
<br />
On the XSI mailing list a few weeks back Dan Yargici posted a <a href="http://groups.google.com/group/xsi_list/msg/6c8d91c1ee15ef55">question</a> about how to reconfigure a simple non-regular pattern like (1,1,5,5,5,5,8,9,9,9,10,10) into (1,1,2,2,2,2,3,4,4,4,5,5). In the resultant thread Martin Chatterjee came back with a brilliant solution without using repeats. Martin's solution touched on some of the inherent functionality in ICE arrays that's worth expanding upon.<br />
<br />
I'm going to try and illustrate some of these with a sample scene that contains an ICE tree that shows several different methods for firstly creating a pattern array and then using that pattern to manipulate an array. If that all sounds abstract it's based on Dan's problem above but with the added wrinkle that the initial pattern is not numerically ascending i.e. it looks something like this: (8,8,2,2,2,14,3,3,1,16,11,11).<br />
<br />
<a name='more'></a>The first task is to identify the points at which the pattern changes e.g. when the preceding item in the array is <span style="font-family: inherit;">not the same as the current one. There are a couple of ways of doing this illustrated in the scene, but it's the first method that illustrates our first point.You can create an identical array and use the<span style="color: #bf9000;"> insert in array </span>node to ad</span>d zero at index zero. Although the arrays are now of different lengths you can subtract the two arrays. Wherever the resultant value is non-zero you can mark the array with a boolean. So, here's the first key point about ICE arrays:<br />
<ul>
<li><i>ICE arrays do not have to be the same size for operations (e.g. subtraction)</i> </li>
</ul>
The subtraction calculation will proceed until one of the arrays runs out and the resultant array will be truncated to that length. It seems like an esoteric point in the documentation, but it's genuinely useful.<br />
<br />
You should now have an array consisting of (1,0,1,0,0,1,1,0,1,1,1,0) i.e a series of boolean values. Each 1 represents the starting point of a new digit in the pattern. In this form it's not much use but if you convert the booleans to integers and then multiply by the subindex array you get a list of indices in the original array where the pattern changes - the actual constituent numbers of the pattern. Multiplying subindices by a boolean (converted to integer) is a neat way of isolating the array indices you're interested in.In this case we get (0,0,2,0,0,5,6,0,8,9,10,0).<br />
<br />
It's still not entirely usable, though, since it also contains a lot of zero entries. If we were to run this new list through a <span style="color: #bf9000;">select in array</span> node we would be picking the zero index entry multiple times. Which brings us to our second point:<br />
<ul>
<li><i> If you feed an index array into the index port of <span style="color: #bf9000;">select in array</span> or <span style="color: #bf9000;">remove from array</span> you get an equally sized** array as your output*. This output array can contain multiple duplicates of an index if you require it. </i><i>(* The values output of <span style="color: #bf9000;">remove from array</span>). </i><i>(**Provided all the input indices are valid - more on this below.)</i></li>
</ul>
What this means is that if you feed (0,0,0,0,0) into the index port of <span style="color: #bf9000;">select in array</span> you will get back an equally sized array with each index of the new array containing the value of index zero from the old array.<br />
<br />
We need to either remove the zero entries or, at least, filter them out in such a way that ICE does not action them. Here's where, I guess, the main trick of this article lies:<br />
<ul>
<li> <i>ICE has been optimised to ignore invalid index entries for arrays</i>. </li>
</ul>
By 'invalid index', I mean any entry for an array index that is either negative or exceeds the array size minus one. There are three key nodes where this is relevant: <span style="color: #bf9000;">remove from array</span>, <span style="color: #bf9000;">select in array</span> and <span style="color: #bf9000;">set in array</span>. If for example, you feed a remove from array node the indices (-1,-5, 99, 0,1,2,3) and your array size is 10 then only the valid indices will be removed (0,1,2,3). In conventional scripting/programming you would never normally use an invalid index value without risking a serious crash. In ICE there's no need for any repeat loops or detours in the data flow to remove them.<br />
<br />
So, in our case, with an array like (0,0,2,0,0,5,6,0,8,9,10,0) where all we're interested in are the non-zero entries we just need to make the zeros into invalid indices (negatives or values that exceed the array size minus one i.e. (-1,-1,2,-1,-1,5,6,-1,8,9,10,-1). This new array can be fed into a select in array node and will only select the following indices (2,5,6,8,9,10). Effectively, you've filtered the array without a repeat loop.The sample scene shows a couple of different ways of doing this.<br />
<br />
The final point to make is that two of the array nodes - insert in array and set in array - can each take two array inputs. One for the indices to be affected and one for the values to be utilised at those indices. As above, those arrays can be different lengths - the processing will truncate the length of the longest array to the shortest. What's more, any invalid indices will be ignored and thus any parallel value (ie. one at the same index) in the value array will also be ignored.<br />
<br />
It's dry and it's boring but being aware of these kinds of optimisations and behaviours of the ICE array nodes can be very useful as, I think, Martin's solution demonstrated.<br />
<br />
Sample scene is <a href="https://www.dropbox.com/s/mjsry90cqxu37jt/sort_pattern.rar?dl=0">here</a>.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4037954350464998026.post-63050859887392336092010-07-25T07:30:00.000-07:002017-03-13T05:49:30.241-07:00Dart Throwing with Weight Maps<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvzq8q-T3elQUo5nCe0r0lNhaGyongxYyttDrWONcwLvaJKJYWzNeptOrEl41VEJpF4vZkLxZxDHU58EKdpE_m1DcuCABRlWbSjNcZVgFh6CMNk-PX0yFM-CAgOiznzo-avhSBKlTF_KQ/s1600/dt2.gif" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5497864978727076194" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvzq8q-T3elQUo5nCe0r0lNhaGyongxYyttDrWONcwLvaJKJYWzNeptOrEl41VEJpF4vZkLxZxDHU58EKdpE_m1DcuCABRlWbSjNcZVgFh6CMNk-PX0yFM-CAgOiznzo-avhSBKlTF_KQ/s400/dt2.gif" style="cursor: pointer; height: 287px; width: 400px;" /></a><br />
<br />
<i>3rd July 2013:</i> Please note: the latest, updated, version of Dart Throw is <a href="http://julianjohnsonsblog.blogspot.co.uk/2013/07/dart-throw-multiple-size.html">here</a>. <br />
<br />
I've just finished a new version of Dart Throwing with weight map control for spacing (spacing maps) and point deletion (erase maps). It uses it's own internal scheme for computing the barycentric weights from weight map values at vertices. Spacing maps allow you to modulate the density of the points using the weight map as an interpolant between the spacing radius and max spacing radius. Erase maps have a threshold parameter which lets you control at what point between 0 and 1 on the weight map the point should be deleted.<br />
<br />
There's also a new 'Iteration Abort' parameter which specifies the number of tries (as a normalised percentage of the total iterations) the plugin should make before it aborts. This is for scenarios where you set a huge number of iterations but the number of successful darts becomes very low i.e. if you set 1,000,000 iterations and you only get an additional 1 dart added in the last 500,000 'tries' then you can see that aborting after 500,000 might be handy. The message window gets logged with the maximum number of iterations for a single try as a reference.<br />
<br />
Changes in the way multiphase/element generator plugins work in the SDK mean that this version is only available for the very latest version of Autodesk Softimage - 2011 SP1. The Addon has been compiled for both 32 and 64bit Windows.<br />
<br />
<a href="https://www.dropbox.com/s/a9h0ghm6eq1xd62/dart_throw_v002.rar?dl=0">Download Dart Throw v002 Addon</a><br />
<br />
A Vimeo clip is <a href="http://vimeo.com/13620647">here</a>.Unknownnoreply@blogger.com12tag:blogger.com,1999:blog-4037954350464998026.post-23160006599143892392010-07-17T02:55:00.000-07:002010-07-18T03:12:21.569-07:00Context Switching Using Set Nodes and Filter<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-uHOiSMO-1VOm40JhAwYfmFAkV8zDvT2SDZXUQJPKRpp6J2XQ7u_vPjuLlcc3aE9tVcl66XrOx9QDRZhQgTNDxx9l9KpAMkUMZIzOFlY6xCSpBO-USK2xQbNaC-GvKrbhCuLrxATUDqc/s1600/set_filter.gif"><img style="cursor: pointer; width: 400px; height: 238px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-uHOiSMO-1VOm40JhAwYfmFAkV8zDvT2SDZXUQJPKRpp6J2XQ7u_vPjuLlcc3aE9tVcl66XrOx9QDRZhQgTNDxx9l9KpAMkUMZIzOFlY6xCSpBO-USK2xQbNaC-GvKrbhCuLrxATUDqc/s400/set_filter.gif" alt="" id="BLOGGER_PHOTO_ID_5495181563193234050" border="0" /></a><br />In the roll object compound below I use the Set nodes to move between point context and object context. Combined with filter, it's a powerful way to access an individual component in a specific context and make it available to all other components in that context.<br /><br />On the list <a href="http://groups.google.co.uk/group/xsi_list/browse_thread/thread/fc1a84f1bd9d8486?hl=en#">here</a> (and on several occasions before), <a href="http://blog.blackredking.org/">Ciaran Moloney</a> has suggested a technique for using Set nodes, Filter and the Repeat node for gathering data in one context and turning it into an object context array. It's a great technique and one which deserves a closer look.<br /><br />Whenever you use a specific context node e.g. point, node, polygon in the branch of an ICE Tree its context takes precedence over any object context nodes in the same branch. As soon as you try and set any data in that branch it will always be in the more granular context. Using the Get Set xx nodes, however, acts as a switch to the context of the branch and turns it back into object context. Put simply if you start off in 'polygon position' context you can finish the branch with a Get xx in Set node which provides you with a single piece of object context data e.g. maximum in set.<br /><br />Ciaran's trick involves using this switching ability to continually iterate over each point, polygon or node and isolate a single item each time - pushing that item onto an object context array.<br /><br />In the tree above I construct an object context array of all the node positions. You can see that the tree starts in node context but then each node has a repeat loop iterating over itself matching it's own element index with the list of all node element indexes. When it finds a match the output is a single node<span style="font-style: italic;"> still in node context</span>. Pumping this into Get Maximum in Set - a filtered set of one - simply switches the output to object context and the node position gets pushed onto an object context array.<br /><br />The downside is obviously iteration time as each node has to iterate NbNodes times over itself and with large numbers of nodes, polygons etc. this could be slow. However, it seems like the only surefire way to construct robust object context arrays of node positions, polygon positions etc.Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4037954350464998026.post-66289098883120012922010-07-16T23:25:00.000-07:002017-03-13T05:52:26.718-07:00Even Spacing on Curve/Normalised U on Curve<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkMd09Gwstq8tIa5eer2SfgP4-nf7kDUB2G8-1VFVAfIRjzO8Ij6vFJ5Mtqs2Id3drtSSM3ukyzO_a5TbW13YNlIn4JjWljBA-9dEL8OcVesBKXSGXsENSWXxKEf2n4Tx_Y97QuOWLmZw/s1600/even.gif" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5494770379083126290" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkMd09Gwstq8tIa5eer2SfgP4-nf7kDUB2G8-1VFVAfIRjzO8Ij6vFJ5Mtqs2Id3drtSSM3ukyzO_a5TbW13YNlIn4JjWljBA-9dEL8OcVesBKXSGXsENSWXxKEf2n4Tx_Y97QuOWLmZw/s400/even.gif" style="cursor: pointer; height: 299px; width: 400px;" /></a><br />
<br />
Following on from a post by Brad Gabe on the mailing list it looked like the existing normalised u compounds on The Area didn't seem to take an array of u values as an input so I decided to revisit Even Spacing on Curve and reformulate so that the user could input an array of (or a single) normalised U value. In the process, I fixed some bugs and hopefully cleaned up the trees a bit. The resulting two compounds are here:<br />
<br />
<a href="http://Even Spaced Curve Positions 2.0">Even Spaced Curve Positions 2.0</a><br />
<br />
<a href="https://www.dropbox.com/s/vo8pswv4p9e36iu/Normalised%20U%20to%20Curve%20Position.rar?dl=0">Normalised U To Curve Position 2.0</a><br />
<br />
For even spacing points on a curve, Helge's Strand Tools provide a much better solution. I don't think there's another compound that accepts an array of normalised U values so the second compound may be useful.<br />
<br />
Let me know if you find any errors.Unknownnoreply@blogger.com8tag:blogger.com,1999:blog-4037954350464998026.post-37564569621290209442009-09-28T06:07:00.000-07:002009-09-28T06:14:30.081-07:00Meshless Deformations in ICEI've just posted a preview of an implementation of meshless deformations in ICE. The system deforms a polygonal mesh using particles and shape matching. It seems like a fairly efficient way of generating various types of soft body deformations whilst preserving the volume of the original mesh.<br /><br /><a href="http://www.vimeo.com/6794261">http://www.vimeo.com/6794261</a><br /><br />I'd love to release the compound soon but the whole area of collision and soft-body/soft-body collision is huge and is definitely going to take some time to implement before it's user friendly!Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4037954350464998026.post-52134184821635720252009-09-26T06:20:00.000-07:002017-03-13T05:53:49.785-07:00Dart Throw Update<i>3rd July 2013:</i> Please note: the latest, updated, version of Dart Throw is <a href="http://julianjohnsonsblog.blogspot.co.uk/2013/07/dart-throw-multiple-size.html">here</a>. <br />
<br />
I've updated the Dart Throw ICE node to version 0.9b. The new version utilises the new port dirty state features in the SDK to prevent the compound firing when you make changes in the overall tree. I've also added a cancel button and re-wired the evaluation cycle. All in all, this version is more stable and usable. Big thanks to <a href="http://warpedspace.org/">Amaan Akram</a> for help and advice with the code.<br />
<br />
<a href="https://www.dropbox.com/s/oy3xgp1wpa9x2rb/dart_throw_0.9b.rar?dl=0">dart_throw_0.9b.rar?dl=0</a><br />
<br />
Please note that due to limitations in the SDK when you cancel an evaluation in progress, the values in the PPG cannot be reset to their original values. CTRL-Z will restore those values.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-GmTauLwGisYPqBK_B9S8WUaJwp5aHNCNCcZVchD6P9fcSFoRe6XQ-sjAWQ2n4LDKgVCf2PW6ib4JlVO-KvHJAB9hXj6NOowjuygeCAS1-ZJD4A6__Jfh2kUeb_DZyGuXa3cUJ3fJHkk/s1600-h/dthrow.jpg"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5385800881095510866" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-GmTauLwGisYPqBK_B9S8WUaJwp5aHNCNCcZVchD6P9fcSFoRe6XQ-sjAWQ2n4LDKgVCf2PW6ib4JlVO-KvHJAB9hXj6NOowjuygeCAS1-ZJD4A6__Jfh2kUeb_DZyGuXa3cUJ3fJHkk/s400/dthrow.jpg" style="cursor: pointer; height: 298px; width: 400px;" /></a>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4037954350464998026.post-56892801336888065082009-09-08T06:54:00.000-07:002013-07-02T22:04:24.664-07:00Dart Throw Custom ICE Node for Softimage 2010<i>3rd July 2013:</i> Please note: the latest, updated, version of Dart Throw is <a href="http://julianjohnsonsblog.blogspot.co.uk/2013/07/dart-throw-multiple-size.html">here</a>. <br />
<br />
I've just finished off a custom ICE node in C++ utilising the new geometry features in the 2010 SDK. The node will let you position random, non-overlapping points on any polygonal geometry. The more iterations you use, the more 'packed' the distribution will be.<br />
<br />
<a href="http://www.vimeo.com/6483842"></a><a href="http://www.vimeo.com/6483842">http://www.vimeo.com/6483842</a><br />
<br />
The nodes are packaged in a RAR file as an Addon with a sample scene here:<br />
<br />
0.9b (Latest version)<br />
<a href="http://www.exch.demon.co.uk/xsi/files/dart_throw_0.9b.rar">http://www.exch.demon.co.uk/xsi/files/dart_throw_0.9b.rar</a><br />
<br />
0.8b<br />
<a href="http://www.exch.demon.co.uk/xsi/files/dart_throw_0.8b.rar">http://www.exch.demon.co.uk/xsi/files/dart_throw_0.8b.rar</a><br />
<br />
It's a beta release a the moment, so please let me know if you have any problems/suggestions. Since it uses features only available in Softimage 2010, it won't work in earlier versions.Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4037954350464998026.post-82649860509099475562009-05-19T04:15:00.000-07:002009-05-19T04:38:38.063-07:00Roll Object Compound and Sample SceneI've just finished cleaning up and, hopefully, optimising the roll object compound. The new compound removes expensive geometry queries in favour of filter and min/max in set. I think it's quicker on larger datasets although the downside is I've had to use more nodes!<br /><br />The lowest point in Y on the object at simulation start becomes the virtual floor. There are many other ways to do this but it seems like a sensible way to keep the compound fairly general. If you want other objects to contact the same floor then their lowest point in Y also needs to be at floor level.<br /><br />The Distance to Angle Ratio parameter controls the ratio of angular change to the distance the driving object travels each frame - higher values rotate the object more, lower values slow down the rotation.<br /><br />Let me know if you have any suggestions, improvements or performance tweaks or if you find any bugs.<br /><br />Scene: <a href="http://www.exch.demon.co.uk/xsi/files/roll_object_scene_v001.rar">http://www.exch.demon.co.uk/xsi/files/roll_object_scene_v001.rar</a><br />Compound: <a href="http://www.exch.demon.co.uk/xsi/files/roll_object_compound_v001.rar">http://www.exch.demon.co.uk/xsi/files/roll_object_compound_v001.rar</a><br /><br />Thanks to Helge and Martin Chatterjee for their resources on similar operators:<br /><a href="http://www.xsi-blog.com/archives/94">Helge's Roll Tutorial</a><br /><a href="http://groups.google.co.uk/group/xsi_list/browse_thread/thread/5fe5b283793853cd/ec1a228048e1ea35?hl=en&lnk=gst&q=rolling+ball#ec1a228048e1ea35">Martin's BallRoll SCOP</a>Unknownnoreply@blogger.com2