I see there is an Extra for Softimage Subscription customers. It’s a plugin that adds two commands for exporting CrowdFX:
Export Crowd as FBX (Null Rig) – Exports a null rig for each actor including the animations created by the crowd simulation
Export Crowd as FBX (Null Rig and Geometry) – In addition to the null rig, it exports one geometry per actor enveloped to the null rig
There’s some docs on the Documentation tab in the Sub center.
Category Archives: ICE CrowdFX
CrowdFX with multiple emitters and different goals
From Manny at Autodesk, here’s a video walkthrough of setting up multiple crowd emitters, and giving each emitter a different goal.
Getting actor data from CrowdFX
Update: oops, it looks like my script below works only in simple cases where you just one actor proxy. The ActorID seems to be a constant (perhaps unused???) and it looks like you have to take the point ID and then look up the corresponding entry in the CrowdFX_Actor_Indices array.
If you need to get info like the actor ID, the X and Z positions, and the animation frame from CrowdFX, you can get it from the Simulation Cloud.
In the screenshot below, I used three Attribute Display properties to display the following:
- Actor ID (I have only one actor)
- PointPosition
- CrowdFX_Actor_CurrentFrameInCycle (an array for each action aka pose on the actor)
Here’s a little Python snippet that logs a comma-separated string that contains the Actor ID, X, and Z positions, PoseID, and CurrentFrameInPose.
Note the use of the logf function from the sipyutils.
# # SOFTIMAGE 2013 # from sipyutils import si # win32com.client.Dispatch('XSI.Application') from sipyutils import siut # win32com.client.Dispatch('XSI.Utils') from sipyutils import siui # win32com.client.Dispatch('XSI.UIToolkit') from sipyutils import simath # win32com.client.Dispatch('XSI.Math') from sipyutils import log # LogMessage from sipyutils import disp # win32com.client.Dispatch from sipyutils import C # win32com.client.constants from sipyutils import logf si = si() pc = si.Dictionary.GetObject( "Crowd.Point_Cloud" ).ActivePrimitive aPtPos = pc.ICEAttributes("PointPosition") log( len(aPtPos.DataArray) ) pos = pc.ICEAttributes("PointPosition").DataArray ids = pc.ICEAttributes("CrowdFX_Actor_ID").DataArray poses = pc.ICEAttributes("CrowdFX_PoseState_ID").DataArray frames = pc.ICEAttributes("CrowdFX_Actor_CurrentFrameInCycle").DataArray2D # ID, X, Y, Z, PoseState, CurrentFrameInCycle for i in range( len(pos) ): logf( "%d, %f, %f, %d, %d", ids[i], pos[i].X, pos[i].Z, poses[i], frames[i][poses[i]] )
The output of this script for frame 126 of the CrowdFX_FooFighters sample scene looks like this:
# INFO : 0, -100.000000, 0.000000, 8.531111, 2, 154 # INFO : 0, -85.714279, 0.000000, 6.684280, 1, 111 # INFO : 0, -71.428574, 0.000000, 7.442898, 2, 131 # INFO : 0, -57.142853, 0.000000, -2.251395, 2, 132 # INFO : 0, -42.857143, 0.000000, 11.363565, 2, 97 # INFO : 0, -28.571426, 0.000000, 7.302890, 2, 149 # INFO : 0, -14.285706, 0.000000, 13.759472, 5, 217 # INFO : 0, 0.000000, 0.000000, 11.584186, 5, 186 # INFO : 0, 14.285721, 0.000000, 9.853815, 3, 167 # INFO : 0, 28.571442, 0.000000, 8.366404, 2, 141 # INFO : 0, 42.857147, 0.000000, 21.238329, 5, 163 # INFO : 0, 57.142868, 0.000000, 6.831881, 5, 222 # INFO : 0, 71.428589, 0.000000, -2.667232, 2, 201 # INFO : 0, 85.714294, 0.000000, 16.321472, 3, 236 # INFO : 0, 100.000000, 0.000000, 10.077105, 2, 93 # INFO : 0, -100.000000, 0.000000, -10.505310, 2, 154 # INFO : 0, -85.714279, 0.000000, -17.066412, 1, 83 # INFO : 0, -71.428574, 0.000000, -11.711117, 5, 152 # INFO : 0, -57.142853, 0.000000, -22.719725, 2, 142 # INFO : 0, -42.857143, 0.000000, -7.311695, 5, 127 # INFO : 0, -28.571426, 0.000000, -11.755372, 2, 151 # INFO : 0, -14.285706, 0.000000, -3.648053, 5, 191 # INFO : 0, 0.000000, 0.000000, -6.797891, 5, 177 # INFO : 0, 14.285721, 0.000000, -8.881895, 5, 101 # INFO : 0, 28.571442, 0.000000, -10.384384, 5, 158 # INFO : 0, 42.857147, 0.000000, 4.351840, 5, 166 # INFO : 0, 57.142868, 0.000000, -11.661755, 2, 178 # INFO : 0, 71.428589, 0.000000, -22.718691, 2, 171 # INFO : 0, 85.714294, 0.000000, -1.260182, 5, 127 # INFO : 0, 100.000000, 0.000000, -8.947992, 5, 123
The Foo Fighter pose state IDs are set here (there are actually eight Action Sources in the ActorProxy property, but not all of them are used).
BTW, is it just me, or do the Attribute Display properties not work with the sample CrowdFX scenes? I was using the Foo Fighters sample at first, but I wasn’t able to show any attribute values, which made it a little harder to figure out what info was where.
Copying tangent data in a crowd
Here’s a video walkthrough that shows how to get tangent data on the source actor and copy it to the actor copies. It’s basically a two-step process: first, copy the tangent data to a custom attribute on the mesh proxy, and the copy the attribute from the proxy to the actor copies. That’s basically what CrowdFX does for you for the default Texture_Projection.
I did this video for a customer who wanted the tangent data for the normal maps on the actor copies.
Crowds and actor texture projections
In this video, I show how to deal with actors that have texture projections with non-default names. The Crowd ICE compounds are set up to look for texture projections with the default “Texture_Coordinates_AUTO.Texture_Projection” name.
The case of the missing crowd
Our first CrowdFX-related case in Product Support!
A customer reported that CrowdFX wasn’t working. When he opened a sample CrowdFX scene, he got all these “plug-in is not installed” errors [Hey, that’s the same error I blogged about yesteday, but this time it’s something different–Steve]
// ERROR : 2356 - This plug-in is not installed: CrowdFX_RigProxy // ERROR : 2356 - This plug-in is not installed: CrowdFX_SkeletonsCloud // ERROR : 2356 - This plug-in is not installed: CrowdFX_ActorProxy // ERROR : 2356 - This plug-in is not installed: CrowdFX_ActorsProxies // ERROR : 2356 - This plug-in is not installed: CrowdFX OpenScene("C:\\Program Files\\Autodesk\\Softimage 2013\\Data\\XSI_SAMPLES\\Scenes\\ICE\\CrowdFX_Walk_Along_Paths.scn", null, null);
The real clue was an error logged at startup:
// ERROR : Traceback (most recent call last): // File "<Script Block 2>", line 55, in XSILoadPlugin // in_reg.RegisterMenu(C.siMenuTbICECrowdFXActorsID,"Actors_Menu",False,True) // File "C:\Python26\lib\site-packages\win32com\client\__init__.py", line 168, in __getattr__ // raise AttributeError, a // AttributeError: siMenuTbICECrowdFXActorsID // - [line 54 in C:\Program Files\Autodesk\Softimage 2013\Addons\CrowdFX\Application\Plugins\CrowdFX_Plugin.py]
First, this shows the customer is using the version of Python 2.6 installed on the system (not the version shipped with Softimage). More importantly, it shows that the CrowdFX constants, like siMenuTbICECrowdFXActorsID, are missing.
For Python, all the Softimage constants like siMenuTbICECrowdFXActorsID are cached in the Python install folder. For example, the Softimage constants are cached in the folder C:\Python26\Lib\site-packages\win32com\gen_py\269C4D8C-E32D-11D3-811D-00A0C9AC19A9x0x1x0\__init__.py
The solution in this case was to zap (delete) the gen_py folder, forcing Softimage to regenerate the generated type info cache.
Coloring crowds – using a custom ICE attribute for the shirt color
I struggled with this for awhile–it wasn’t easy to get my custom ShirtColor attribute to show up in the Color Attribute shader.
Coloring crowds
Here’s my re-make of Guillaume Laforge’s “Crowd colors” video that was posted on the Softimage mailing list.
In this video, we show you how to:
- Use an ICE attribute on the crowd mesh to randomize the colors in a material
- Get the particle colors and using them for the material color