9
$\begingroup$

So I have an complex smooth surface. I created a high resolution path curve and used a Shrink Wrap modifier to make it fit on my surface where I want it. I apply the shrink wrap.

I can easily make an object move along this path now with a Follow Path constraint. Great.

But...I would like to animate a ball rolling along this path. I can't find a constraint or other tool in Blender that allows for this. If I knew how Python interacts with Blender better (I'm just learning) I would write something using quaternions (I've done this in an iOS physics engine I did a few years back).

Or is there some trick with rigid body simulation to make my ball roll along the constrained path?

What's an animator to do?

$\endgroup$
  • $\begingroup$ It might be possible to do something with a curve guide force field and the rigid body simulator. I'll give this a try later. $\endgroup$ – gandalf3 Dec 25 '14 at 21:07
  • $\begingroup$ Seems curve guides don't affect rigid bodies? Odd, as there is an influence slider.. Perhaps a bug. $\endgroup$ – gandalf3 Dec 26 '14 at 6:21
22
$\begingroup$

You can make the ball roll with a Driver, first - this is what you should already have setuped, make sure the ball's Follow Path constraint option Follow Curve is set:

enter image description here

Add single driver to the X axis rotation field (RMB on field > Add Single Driver R)

enter image description here

Setup the driver like this (scripted type, no variables), also make sure Auto Run Python Scripts in User_Preferences > File is enabled:

enter image description here

Lets add a driver variable for the curve evaluation time, call the variable "eval_time", in the Prop field put the curve and Path is eval_time:

enter image description here

Now its time for the driver expression. You will need to know the ball's diameter and the curve's length.

  • diameter you get from ball's dimensions in properties panel N:
  • curve's length you get from running this script with curve selected:

    import bpy
    import bmesh
    orig = bpy.context.active_object.name
    bpy.ops.object.duplicate_move()
    bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
    bpy.ops.object.convert(target='MESH', keep_original=False)
    bm = bmesh.new()
    bm.from_mesh(bpy.context.active_object.data)
    edge_length = 0
    for edge in bm.edges:
        edge_length += edge.calc_length()
    bpy.context.window_manager.clipboard = str(round(edge_length,3))
    bpy.ops.object.delete()
    bpy.context.scene.objects.active = bpy.context.scene.objects[orig]
    bpy.context.object.select = True
    

    It will calculate the length and store it in the clipboard, you can then paste it with Ctrl+V.

The driver expression is: -2 * curve_length / diameter * ( eval_time / eval_max ):

enter image description here

Now the ball will roll accordingly to your curve's Evaluation Time:

enter image description here

$\endgroup$
  • 2
    $\begingroup$ This is awesome! Thanks. Now I have to read up on this stuff so I can do things like this myself. The more I learn, the less I know. :-) $\endgroup$ – Chuck Dec 26 '14 at 4:26
  • 3
    $\begingroup$ This video is a good start to drivers. $\endgroup$ – sambler Dec 26 '14 at 8:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.