Jump to content


  • Content count

  • Donations

    0.00 CAD 
  • Joined

  • Last visited

Community Reputation

9 Neutral

About Alain2131

  • Rank

Personal Information

  • Name
  • Location

Recent Profile Visitors

663 profile views
  1. Export crowd agents to USD

    Hi ! I don't know about USD (I only know the base of what it is), but agents are quite reluctant to being exported out of Houdini Just exporting to FBX is "not possible", unless you write a custom tool to convert the packed agent to "actual geometry", like in here But this is NOT made for multiple agents. Haven't tested, but maybe just 5 would be slow, and 100 be painful So maybe (hopefully) someone will come along and say that with USD, it's actually surprisingly simple But with my experience with Agents and trying to export them to FBX, that's a big oof Sorry for not being super helpful
  2. BBox Rotate by Max Length?

    Here's my take on it By the way, thanks Noobini, I've always wondered what dihedral did. With this, I now got a better understanding of it This is a VEX-heavy method of doing it. I compute the rotation matrix and bring back to the origin, then find the longest and shortest side, and finally align the piece according the orientation we want, using dihedral. align_bounds_longest_shortest.hipnc
  3. Export Crowd Agent to FBX

    Hey Michiel, Funny you mentioned that video, since this is where I got the idea to try and use agents to solve my problem ! He showed at 21:32 that he modified the animation manually, and transferred it back onto the rig using some IK function from the agent suite of VEX functions. I thought "Hey, I could do the same !". And indeed I could. I'm curious about the "renormalisation of the output" you mentioned.. An example would be appreciated. My guess is that it would make the normalized animation not fit 100% the original, but I would like to see it for myself I personally don't need the fullbodyik for my current needs, but I might investigate it to know how I could (ab)use it For the scaling, I might allow for an option to bake it onto the points (as I am doing) but with the addition of using the animated scale, that way there won't be any issues importing and exporting it around, since it's just positions (so as you said, "recording" it onto the point cloud). I would appreciate to get in touch with you ! Discussing this with someone would be awesome
  4. Export Crowd Agent to FBX

    Interesting file ! It took me a little while to understand where the Constraint Network was.. Or should I say "Constraint Networks", one inside each "bone" I don't know if doing a setup with only one constraint network for all the bones would be faster. That would be a nice thing to investigate The huge advantage with your method is that it doesn't require any baking, you have real-time result on the "real" mesh There also seem to be no fuss at all for scaling non-uniformly (even though I would try to never do that, it's still nice to have the possibility) Looks indeed robust. You pretty much pointed out my intended use case Let's say I have an FBX of a tree that is rigged and skinned for simulation. What I need is an idle animation of it in the wind, possibly at different wind strength. The idea would be to import it as an agent, create a polyline rig from the actual bones, and plug it into a Vellum simulation for the dynamics. Now, normally, we would just transfer the animation back into the mesh with pointdeform (I assume, I've never done it myself), but that doesn't help me - I need to export this animation to a game engine. A point cache won't work, I need animated bones. Right then, a good thing to note is that agents has a suite of handy dandy VEX functions to modify them, even when they're still packed (see manual_anim - it's the same, but a simulated input is used instead of transforming manually). So I just transfer the animation from the simulation back onto the agent, and BAM. It's "baked" onto a "real" bone hierarchy. The problem was then the question of this thread... How am I supposed to get it out of Houdini now ? Which has been answered - hack it. My intent from the start was to abuse the agent workflow for this use (these VEX functions were all I needed) Using your setup, this exact idea I mentioned is even easier - no need to transfer it back onto the agent at all, the constraint network takes care of that. Neat ! As for my setup, I intend to eventually be able to export more than one agent at a time (so it could be used to actually export a simulated crowd) - although it will surely get pretty slow when exporting tens or hundreds of agents at once (generating a skeleton for each of them, then baking the animation individually). But I foresee some kind of setup using TOPS that just imports the mesh, generate the polyline necessary for the simulation, simulates it, and then export it back into FBX.... The completion of this idea will depend of my needs. There is sure to be a HEAP of issues with this. It's just an idea. In the meantime, I fixed the scaling issue - but it is nowhere as convenient as yours on this point. It just gets rid of any scaling in SOP by applying it directly on the points' position before handing off the geometry to the script. And it uses only the X component, so only Uniform Scaling. And no scale animation. But eh, when is it that there is animated scale on a rig ? Especially in-game, it is often not supported. So I don't feel too bad about this. I attached only the HDAnc, since it's the only thing that changed. The only change is that scaling thing. Bake_Crowd_Agent_To_FBX.hdanc
  5. Export Crowd Agent to FBX

    I agree, why isn't it possible straight away ?.. Anyways, I've just tried the tool with Houdini FX, and exporting the result to FBX and importing in Maya works almost as intended Sure, I need to set the Units to Millimeters in the Import Dialog in Maya to have a sensible scale, and sure, if the first bone has been scaled it will be huge in Maya, but the animation is there The first bone is scaled because of the initial import in Houdini with the Agent SOP. It seems to automatically scale down (or up) the first bone to account for the unit difference. That makes this issue down the line, and I'd like to fix it. I've actually got a fix (for every bones, starting from the root, transfer the scale factor down the line and accumulate it, and finally scale the local translate of every bone by the scale factor. This way I won't have to actually scale the bone) It seems to work with my test case (the one seen above), but there are a few things I need to tweak for it to really work
  6. Export Crowd Agent to FBX

    Hello Michiel, thanks for the answer ! Yeap, that's what I figured I would love to know what sort of a setup you made ! In the meantime, I did a proof-of-concept HDA (non-commercial, so we can't export the result to FBX) for this, following your advice to "hack it" (I actually meant to do the tool earlier, but my attention diverted to other things. Your answer made me come back to it and actually make the tool) It is by no mean flawless, but seems to work quite well with the three tests I did export_agent_fbx.zip
  7. Hey guys ! I have a simple crowd agent that I put some anim onto in SOPs What I do on the agent doesn't really matter, what I need is to export the agent with the animation to FBX I tried simply exporting it with the FBX ROP, but the result was a point cache with no bones How is one supposed to export a Crowd Agent to FBX ? I searched online, and haven't found a working solution Attached is the simple setup in Apprentice (I know Apprentice can't export FBX. That's just an example scene from my home - at work we have the FX version) export_agent_fbx.zip
  8. Houdini not exporting geometry to FBX?

    Hey @rygo6, About tutorials for that, I don't have any specifics about this, I've just referred heavily on the documentation, and watched most of SideFX's vimeo channel videos. This is mainly (badly-written and not optimized) Python, and logic within the Houdini nodes I've just one video on HDA building by Jeff Wagner, which certainly helped me. Sorry for not having more from the top of my head As for the meshes to have the same name as the original group. First, it doesn't use groups (since one point or prim could be in multiple groups) So, I'm guessing that you could transfert the group with an attribute wrangle like so string primGroups[] = detailintrinsic(0, "primitivegroups"); // Get all the groups for(int i=0; i<len(primGroups); i++) // Run over all the groups { int isInGroup = inprimgroup(0, primGroups[i], @primnum); if(isInGroup) setprimattrib(0, "name", @primnum, primGroups[i]); // If the current primitive is in the group, write the group's name in the "name" string attribute, which will be used by the export tool } This is for primitive groups, and needs to be ran in a wrangle set to run over prims. If one point or prim is in multiple groups, this wrangle will prioritize by inverted alphabetical order. Group "Zebra" will win over group "Wolf". The tool will use that name attribute to separate the geometry in individual meshes, and the name will propagate to each meshes. What was that about the materials ? I haven't done anything about them. I'm guessing the issue is if the geo has a material on it at the OBJ level (and not on the actual geometry), the tool would ignore it. That would require a small update to the tool if that is the case P.S. Now I've got a question for you (or people that uses the tool) Would you want groups to work with the tool ? The workaround would be that if there is some point or prim that is referenced by more than one group, the tool will duplicate those and put them is the groups as specified Now This is just the idea, it may be more complicated than that. But hopefully it's as "simple" as that !
  9. Copy multiple objects to multiple point in loop

    Hey there, So for the setpointgroup You misunderstood the process a bit. It does not actually use the detail attribute - the detail attribute is simply set, and not used anymore in the wrangle. int iteration = detail(1, "iteration"); // Gets the current iteration value of the loop, using the detail attribute of foreach_begin1_metadata2 (that is the input 1) int ptCount = npoints(0); // This returns the number of points (in this case, how many chunks you have) // The rand() function produces a random number between 0 and 1 // Using it with the iteration value makes it yield a different number for each scattered point // Since the number is between 0 and 1, if I multiply it by the number of chunks (in this case 20), you'll have a number ranging from 0 to 20 // Doing fit01(rand(iteration + ch("seed")), 0, ptCount) would essentially give the same result. Make use of what you're most confortable with ! int toKeep = int(rand(iteration + ch("seed")) * ptCount); // Maybe that using the same names for those next lines was a bit confusing setdetailattrib(0, "toKeep", toKeep); // This places the variable toKeep in a detail attribute named toKeep. A simple copy/paste setpointgroup(0, "toKeep", toKeep, 1); // This uses the variable toKeep (which has nothing to do with the detail attribute) to say "I want to set a group on the points, please use the geometry of the input 0, the group name is "toKeep" (if it doesn't exist, it creates it), put it on the point number toKeep (which contains a value ranging from 0 to 20), and tell that point to be in the group (the 1 takes care of that)". Because by default groups are initialised at 0, all the other points won't be in the group Another way of doing it is this int iteration = detail(1, "iteration"); int ptCount = npoints(0); int toKeep = fit01(rand(iteration + ch("seed")), 0, ptCount); setpointgroup(0, "currentChunk", toKeep, 1); Hopefully this isn't more confusing To understand the nmin/nmax values in the fit01, you need to understand the principle behind the whole wrangle. Just to mention, those stands for OMin (Original Min), OMax (Original Max), NMin (New Min), NMax (New Max) The idea is to give a different number for each scattered point that represents one of the chunk you have. So if the number is 13, well, simply keep the chunk #13, remove everything else, and copy that chunk on the current scattered point of the loop. So for the nmin, we want the lowest chunk number, which is 0. You can see that in the geometry spreadsheet. As for the nmax, in this case this is the number of chunks that you have, since this is the whole idea of that setup. So, it is ptCount. There is no omin/omax, this is only for the fit() function. The fit01() assumes omin=0 and omax=1. As for the Attribute VOP method, I can't currently produce a scene file since I'm at work. But here's a picture of a few corrections You were using the ptnum output, which is the current number of the point. Just use the numpt, this is the point count (hovering your mouse over it tells you what it is) Using the fit does the exact same result as the multiply. Use what you want ! As for creating a group from the detail attribute, I now understand what you mean. It's because of the VOP method that doesn't have an easy way of doing groups. As far as I know. I've never created groups with it (although is it definitely possible), so I don't know how to set a group the way we need in VOP. Sorry 'bout that. EDIT : I don't know if that makes it simpler, but this may make the connection a bit better between VEX and VOP int iteration = detail(1, "iteration"); int toKeep = int(rand(iteration + ch("seed")) * @numpt); // Using the @numpt, which is the same name as in VOP // That way we get rid of the whole ptCount line setpointgroup(0, "toKeep", toKeep, 1);
  10. Copy multiple objects to multiple point in loop

    No worries The two functions do something similar setdetailattrib -> There are points, vertex, primitive and detail attribute on any piece of geo. Detail is an convenient way to set something that is "global" to the piece of geo you currently have, as it is only there once in memory (instead of on all the points/verts/prims). So go in the details tab of the geometry spreadsheet, and you'll see a "toKeep" attribute. For its use, see below.. setpointgroup -> It does what it says - it sets a point group, much like the group node does. See in the points tab of the geometry spreadsheet, when seleting the wrangle you'll have a new group, named "toKeep". For its use, again, see below.. Oh well, I've just seen that you said that you know what the functions does. Eh ¯\_(ツ)_/¯ Why I said that using groups is easier is for what's below the wrangle. There are two blast node. Why two ? One to showcase the attribute workflow (setdetailattribute), and the other to showcase the group workflow (setpointgroup). If you see the blast nodes underneath the wrangle, one is for the group workflow, and one is for the attribute workflow. The only difference is what's in the "Group" parameter. Using the group workflow, you simply put "toKeep". That's it, easy enough. Using the attribute workflow, the syntax is weirder. `detail(0, "toKeep", 0)` This means "go and get me a detail attribute of the input 0 (the only one in this case) with the name of 'toKeep'", and the last 0 I'm not sure. And the `` are important. I think this is used to return a string, but don't quote me on that. Now, why I said that I could have used an attribute instead is that it is just a bit less expensive memory side, since it's just one attribute instead of one on all the points. But the gain is sooooooooo small that eh, whatever (unless you have millions of pieces, in that case maybe consider it). It all boils down to your personal preference Hope that clears it up a bit !
  11. Copy multiple objects to multiple point in loop

    Hey there ! copyToPoints_1.hipnc Here's what I did. Your pieces were already packed, which is needed for my setup. In the for each loop where you copy the pieces to the points, I added a wrangle that gathers the iteration value of the loop. Based on that, I generated a random number going from 0 to the max number of points (rand(iteration)*pointCount), which gave me the piece that will be copied onto the point of the current loop iteration. I then created a group containing only that piece (yesh I know I could have used an attribute instead, but the group is simpler to understand) and deleted what's not in that group. Hope that's useful ! Have a great day
  12. Causing Waves in the clouds

    This could be a start cloud_flyby_velocity.hip Basically, using the tube idea, use the normals as velocity and add it to the simulation. Hope that's useful !
  13. Houdini not exporting geometry to FBX?

    @zarralax Sorry for the delay, didn't see it. Unsure what you mean by saying "retain each objects' pivot" This could apply to multiple things 1 - Inherit the container's pivot 2 - If it is a packed prim, take that pivot (packedfulltransform) 3 - Take the center as a pivot They could be added as parameters to the tool, if this is what you mean @art3mis I'm glad it's useful !
  14. Hey guys ! Let's lay out the bases. What's the big idea. To start with, I've got some skinned mesh (a tree or something) that I want a wire sim to be applied to. I get the bones' position and parenting information, create a polyline representation of the bones, and then send that to a wire sim. I then need to gather the result and apply it back to the bones. The problem is - the information from the wire sim (pos and orient) are world-space. I need them local-space to be written back onto the bones, and I need them "zero-based", so that a local translation is not applied two times, idem for rotation. Don't know how to make that conversion. Now ! For what I've actually managed to achieve. For the test, I've got no geometry, only very simple bones (a two-bones chain), and I got them into sops in polyline, and the sim is applied to it. I now need to write that info to the bones. That's where I hit a wall. Can someone help me with that ? Either by how to convert the world-space wire sim to the local-space of the bones, or by some trick with nodes (such as sticky/rivets, which is what I'm trying in the hip file). See the aforementioned for some of the tests that I did. TL;DR : I need to transfer a wire sim (that has its initial positions from bones) to their respective bones. See hip file for current tests state. Thanks ! wire_to_bones.hip
  15. I've figured it out. I'm not sure what the timeshift does, but it's not what I need. I need the shift node, with $C put into the Scroll Offset, and change the Units to Frames in the Common tab. The shift node needs to be placed somewhere that has more than one channel (duh), and in my case under the math node was the correct location. The behavior will the that the first channel will have 0 frame of offset, the second will have 1 frame of offset, the third will have 2 frames, and so on. If I would have left the Units in Seconds, it would be 0, 1, 2 seconds of offset. Makes sense, but I didn't know about that when asking the question. Sooo, yeah, that's it ! Thanks for reading !