Outputting a houdini engine animation when baking an asset

   4505   9   1
User Avatar
Member
9 posts
Joined: Nov. 2017
Offline
I've been buiding a destruction asset in Houdini in an attempt to save some time in my usual process in maya.

I used to use:
  • an in maya vornoi script
  • have bullet simulate it
  • bake the animation
  • convert it to a rigged object
Then I'd do some further post processing depending on where the output needs to go. (Game Engine or Others I'm working with)

I'm currently aiming to use the houdini engine plugin to try and replace the preparation half of the process. I.e. the voronoi, simulation and bake.

I've made it to a point where my fractured object at least outputs as a seperate mesh per fracture piece once I bake the asset. (which would be my old method voronoi output)
Now I'm unsure how to get the animation to potentially be baked onto each piece (each mesh is rigid they don't change shape in the animation comming out of houdini. I'm using an rbd bullet solver node to make it)


Most things I can find on my own would have me export the mesh from maya into houdini do the whole sim and fracture process there and used rdb to fbx back into maya to have an output as I want it to be.
I'm hoping it is possible just do the animation via engine. Forgoing to two fbx steps in between.

I'm still pretty new to houdini, so any pointers would be most helpful… If this is even possible to begin with.
User Avatar
Staff
464 posts
Joined: Aug. 2019
Offline
Hi there,

I have attached an HDA that will show you how to set up the simulation part of this.

Essentially you need to create a subnet inside of a Geometry object, and set up your DOP network. In the example, I have placed a ground plane at the origin. You then turn this subnet into a digital asset, and load it into Maya. Inside of Maya, if you pass in multiple pieces of geometry, it will add them to a merge node before providing them to the HDA. However, you may notice a problem if you, for example, add two cubes to the HDA in Maya. They are output as a single mesh! The way we get around this is by getting the assemble SOP to output a group based on the input objects. In Maya, we then check “Split Geo by Group” in order to get multiple pieces of geometry back.

If you want to add fracturing to this, I would install the HDA into Houdini, then make the asset editable. Add what you need, then right click on the asset and select “Save Asset Type”. Then test it in Maya.

Let me know if you have any further questions.
Edited by johnmather - March 20, 2020 14:06:59

Attachments:
bulletsim.hda (40.2 KB)

User Avatar
Member
9 posts
Joined: Nov. 2017
Offline
Thanks for your response.

Sadly enough it doesn't really solve the problem I'm really having, but does clarify what the minimum is for some simulation

I already solved the fracture and making sure it is output as individual pieces in maya from the engine asset.

What I'm genuinely struggling with/stuck on is that I need the animation to be keyframed on the output meshes.
Atleast instead of what I assume is blend shapes? Or engine specific wizardry?


I'm starting to think I'll need to do some hacky constraints on the maya end to get what I'd like to have as output.

I'll include my current setup as a point of reference.

Image Not Found

Attachments:
Fracture_Attempt.hda (101.5 KB)

User Avatar
Staff
464 posts
Joined: Aug. 2019
Offline
Unfortunately transformation based animation is not supported by the Maya plugin at this time. As you have seen, the transforms are not brought over. Instead, the vertices are updated per frame. This allows the number of vertices to change over time.

A possible solution to your issue would be to write a script to do the following:

for each geo piece
create a bone
create a Point on Poly constraint between bone and vertex 0 of current piece
bake the animation of the bone
go to frame 0
duplicate the piece to remove it from engine control
constrain duplicate to baked bone
Edited by johnmather - March 23, 2020 11:17:12
User Avatar
Member
9 posts
Joined: Nov. 2017
Offline
Ok I got a pretty good handle on maya scripting to do that instead

Thx for the pseudo code to get me on track!
User Avatar
Staff
464 posts
Joined: Aug. 2019
Offline
No worries. I just updated the pseudo code above to fix an error. You cannot move the bone as it makes the transform incorrect.

Edit: Looking at this again, you could create a secondary bone, move it to the center of the bounding box, then add a parent constraint to the original bone. That will keep a constant offset. You would then bake the animation of this joint.

It seems like the Maya bake animation tool can cause issues with these joints. From what I can observe, it seems like it isn't waiting for Houdini to return the results, which can cause pops in the animation. You should be able to get around this by writing your own loop to bake the animation out manually.
Edited by johnmather - March 23, 2020 12:02:00
User Avatar
Member
9 posts
Joined: Nov. 2017
Offline
So I managed to make it to something… Mostly functional :/

Some bones didn't seem to transfer animation so I tried all sorts of sillyness like querrying the dependency node, refreshing the
viewport, multithreading it and waiting for a bit on a second thread before each frame bake.

None of that worked so I eventually ripped the whole thing appart again.
I've come to the conclusion that the issues occurs with the Point on Poly constraint
I had already concluded in manual test with just regular maya meshes that maintain offset was no go on it… So I don't use it in script. (Bone just goes to world 0 and no follows what so ever)

The constraint is like Shrodingers Cat. Does it work? You won't find out till you try.
On average 7-ish of the constraints fail. (Got about 50 pieces in my test case)
Even looping over every vert to try and link to hopelessly doesn't work. Tried deleting the joint and constraint and trying again as well as replacing the failing joint with a polycube, because why not. No luck in any case. I opened the box and it's dead don't bother trying to revive the constraint.
Also fun. It's not concistent between attempts who fails either. (I reopen the test maya file without saving to try again)

I don't know if you guys got any ideas or advice to maybe revive this little constraint from hell. I might need to report this to Autodesk that their constraint is faulty.

If I did it right I attached a zip with my HDA, test script and test maya file. Just in case I'm missing something on the houdini end that you guys can point out.

Attachments:
HelpPackage.zip (141.9 KB)

User Avatar
Staff
464 posts
Joined: Aug. 2019
Offline
Ok, that's something we can work around.

Please find attached a gizmo that I have made that will create an aligned bone from three point positions.

import gizmo

for each geo piece
create piece "master" bone

for each frame
set gizmo|firstPoint to world space position of first geo vertex
set gizmo|secondPoint to world space position of second geo vertex
set gizmo|thirdPoint to world space position of third geo vertex
key master bone's translation and rotation values to that of gizmo|result

Attachments:
alignBoneToPointsGizmo.ma (73.6 KB)

User Avatar
Member
9 posts
Joined: Nov. 2017
Offline
So… I've been down a rabbit hole, but I've made it to a proper result!

Sadly enough the rig you provided had the rotations compeletly flip 180 degrees rather randomly. Everything did move though.

Since we're in the case of this rig already following 3 points on the meshes and with the help of a more mathematical cued in brain than mine and the maya API I tried a completely different approach.

Initially I tried following the first 4 vertices to create tetrahedron postion matrixes.

I keep the start state of each matrix and create a new one per frame.
As a note the maya API likes to garbadge collect allot of it's more primitive objects if you leave the scope of a method (this includes class inits). So I had to create a new OpenMaya.MMatrix for the start frame for every frame bake.
I've had to deal with similar conflicts with garbage collection when querrying vert colours on a mesh.

The magical function is:
startPositions . TransformMatrix = newPositions
Since we're looking for the transform matrix we transform the function to:
transformMatrix = inverse(startPositions) * newPositions

in practice this leads to the following lines of code:
transformMatrix = startPositions.inverse() * newPositions
transformMatrix = om.MTransformationMatrix(transformMatrix)

in this om is maya.api.OpenMaya and the position variables are an instance of MMatrix where each row is a point as (x, y, z, 1)

There was one more snag though. Some objects could really go of kilter with this approach. The assumption was that some of the tetrahedrons we were collecting were almost a strip of points. Leading to a situation, as I understand it, that the matrix can't be correctly inversed.
Maya doesn't block against bad inverse input.

So we changed the points to the first 3 points of a polygon and a fourth point in the center of these 3 points offset by this poly it's normal. Just to guarentee a sensible shape being used without too much validation code.

In practice to get the point matrix you run code like this:
polyNormal = self.fnMesh.getPolygonNormal(0)
vertices = self.fnMesh.getPolygonVertices(0)
point0 = self.fnMesh.getPoint(vertices[0], om.MSpace.kWorld)
point1 = self.fnMesh.getPoint(vertices[1], om.MSpace.kWorld)
point2 = self.fnMesh.getPoint(vertices[2], om.MSpace.kWorld)
        
x_center = (point0.x + point1.x + point2.x) /3
y_center = (point0.y + point1.y + point2.y) /3
z_center = (point0.z + point1.z + point2.z) /3
        
point3 = om.MPoint(polyNormal.x + x_center, polyNormal.y + y_center, polyNormal.z + z_center)
        
values = [point0, point1, point2, point3]
values = [(p[0], p[1], p[2], p[3]) for p in values]
tetraMatrix = om.MMatrix((values[0], values[1], values[2], values[3]))

Technically this approach will support meshes that translate, rotate and scale.

I'm sharing the info in case anybody else googles their way to this thread and to confirm that my issues for at least roundabout animation baking houdini destruction are resolved.

Thx for all the input and help allong the way
Edited by toxkillfraex - April 1, 2020 04:55:12
User Avatar
Staff
464 posts
Joined: Aug. 2019
Offline
Hi toxkillfraex, I'm glad that you were able to solve your issue, and thank you very much for posting your solution here. I'll have to give it a go myself.
  • Quick Links