Jump to content

packed primitives: from simulation to render


jkunz07

Recommended Posts

I was wondering what the recommended workflow is for simulating a bunch of objects using packed primitives and then rendering them with motion blur.

 

I've been conducting some tests and here's what I've found so far:

 

I tried importing the packed geo from dops and rendering that - it didn't show up in the render, no errors or anything reported by Mantra even after increasing verbosity.

While this is a bit odd it's not a to concerning for me, as the packed primitives aren't packed disk primitives it would be pretty inefficient to write them to disk or render them this way as a copy of the entire geometry would be stored for each frame.

 

So I unpacked the geo, computed v with a trail sop and rendered with geometry velocity blur.  This works and gives be rendered images i'm pleased with, but I can see it becoming pretty heavy and inefficient for really large sims.  This method is also storing a copy of the entire geo (with additional v attribute) for every frame so the amount of disk space used by this method can grow quite large very quickly.

 

I also tried writing out the geometry before sim, each piece a separate .bgeo file.  Reading the pieces back in as packed disk primitives, then using the transform pieces sop to transform each packed disk primitive by it's corresponding simulation point.

I couldn't really get this working, trying to use geometry deformation samples for motion blur always yielded some pretty odd results.

 

Finally I made a subnet with a geometry object for every piece.  Inside the geometry containers, the corresponding piece is read in through a file sop, bringing the geo in as a packed disk primitive.  The simulation animation is baked into each objects translation and rotation parameters.  This let's motion blur be calculated using transformation time samples.  The geometry is much lighter too, as only on copy of the geometry must be saved for the entire animation, the geometry also doesn't need to have any v attribute. 

 

Here is a frame rendered using this method (The motion blur is all from xform time samples, only 1 geometry time sample, and no v attribute on geometry):

post-6960-0-02495200-1417404020_thumb.pn

 

My only concern is that this is very cumbersome, surely there must be a better way without having to create all these objects and animation channels for every fragment in your packed rbd sim?!  :wacko:

post-6960-0-27525800-1417404250_thumb.pn

Edited by jkunz07
Link to comment
Share on other sites

OK, I think I've sorted this out.

 

The best solution I found was to write out each piece as a separate .bgeo file.

 

So you would have like $HIP/geo/piece1.bgeo, $HIP/geo/piece2.bgeo, $HIP/geo/piece3.bgeo... etc.

 

Then these pieces get read in, each one as a packed disk primitive and merged together like so:

post-6960-0-60189400-1417540708_thumb.pn

 

The packed disk pieces can be moved using xformpieces sop and the simulation points cached from the sim (dopimport "Create Points to Represent Objects").  The timeblend sop can then be used to generate sub frame data.  So this can be rendered with geometry deformation blur giving you non-linear motion blur, really light .ifd files too cause everything is packed disk.

 

 

I guess this is a better method then what I was doing previously although it's still a little counter-intuitive as you have to unlock the file merge to enable reading geo as packed disk.  It is nice not to have to rely on scripts to bake the geo into the file though, especially as that can cause .hip files to become enormous pretty quickly.

 

I'm thinking it still may be useful to bake sim xforms to object level xforms though, as this would allow for a nicely exported alembic hierarchy.

 

Here is a file containing both methods of rendering with multi seg motion blur, transforming pieces at render-time.

rbd_mo_blur.tar.gz

 

The script to bake xforms is in the session module of the file, but I'll also put it here as it might be helpful

def bake_sim_anim():
        # The simulated packed geometry (fetch packed geometry from dop network)
        xfrom_pts = hou.node('/obj/rbd_packed_bullet/simulation_xform_pts')
        # Find how many pieces are in the simulated object
        # I guess we can't add or remove pieces during the sim if we're gonna do this method
        num_pieces = len(xfrom_pts.geometry().iterPoints())
        # Make a subnet to store all the piece geometry objects in
        piece_subnet = hou.node('/obj').createNode("subnet", "bake_pieces_anim")
        # Fill the subnet with pieces
        for i in range(num_pieces):
                piece_geo = piece_subnet.createNode("geo", "piece"+str(i))
                # Setup the file sop in every piece to load it's piece geo from disk
                piece_file = hou.node(piece_geo.path()+'/file1')
                hou.parm(piece_file.path()+'/missingframe').set(1)
                hou.parm(piece_file.path()+'/loadtype').set('delayed')
                hou.parm(piece_file.path()+'/viewportlod').set(0)
                hou.parm(piece_file.path()+'/file').set('$HIP/geo/piece'+str(i)+'.bgeo')
                # Set the pivot parameter of each piece
                hou.parmTuple(piece_geo.path()+'/p').set(xfrom_pts.geometry().iterPoints()[i].attribValue("pivot"))
        piece_subnet.layoutChildren()

        # Frame range to bake animation
        fstart = 1001
        fend = 1096
        finc = 1
        cur_frame = fstart
        while cur_frame <= fend:
                hou.setFrame(cur_frame)
                for i in range(num_pieces):
                        piv = hou.hmath.buildTranslate(hou.Vector3(xfrom_pts.geometry().iterPoints()[i].attribValue("pivot")))
                        # Roation matrix4 from primintrinsic
                        tran = piv.inverted()
                        tran *= hou.Matrix4(hou.Quaternion(xfrom_pts.geometry().iterPoints()[i].attribValue("orient")).extractRotationMatrix3())
                        # Xfrom matrix4 containing point translation
                        #tran *= hou.hmath.buildTranslate(packed_geo.geometry().iterPoints()[i].position()-hou.Vector3(packed_geo.geometry().prims()[i].intrinsicValue("pivot")))
                        tran *= hou.hmath.buildTranslate(xfrom_pts.geometry().iterPoints()[i].position())
                        # Set parameter on object node
                        hou.node(piece_subnet.path()+'/piece'+str(i)).setParmTransform(tran)
                        # Bake current value of translation and rotation parms into keyframes
                        for parm in hou.parmTuple(piece_subnet.path()+'/piece'+str(i)+'/t'):
                                hou_keyframe = hou.Keyframe()
                                hou_keyframe.setTime(hou.time())
                                hou_keyframe.setValue(parm.eval())
                                hou_keyframe.setExpression("linear()", hou.exprLanguage.Hscript)
                                parm.setKeyframe(hou_keyframe)
                        for parm in hou.parmTuple(piece_subnet.path()+'/piece'+str(i)+'/r'):
                                hou_keyframe = hou.Keyframe()
                                hou_keyframe.setTime(hou.time())
                                hou_keyframe.setValue(parm.eval())
                                hou_keyframe.setExpression("linear()", hou.exprLanguage.Hscript)
                                parm.setKeyframe(hou_keyframe)
                # Increment the frame number    
                cur_frame += finc
  • Like 1
Link to comment
Share on other sites

# I guess we can't add or remove pieces during the sim if we're gonna do this method

 

 

I believe you can if you nest the for-loops inside the while-loop. For examples:

for every frame:
    for each piece:
         if piece has not been created inside the subnet:
              create it.
         set keyframes
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...