How can we animate a ball rolling over a path?

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?

• 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. – gandalf3 Dec 25 '14 at 21:07
• Seems curve guides don't affect rigid bodies? Odd, as there is an influence slider.. Perhaps a bug. – gandalf3 Dec 26 '14 at 6:21

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:

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

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

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:

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 ):

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

• 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. :-) – Chuck Dec 26 '14 at 4:26
• This video is a good start to drivers. – sambler Dec 26 '14 at 8:50