11
$\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$
2
  • $\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, 2014 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, 2014 at 6:21

1 Answer 1

25
$\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

Let's break the expression down:

  • (eval_time/eval_max) is the only element that changes and it goes from 0 to 1 as the ball moves along the curve

  • the rest equates to a number, that says how much has the ball turn to rotate along the whole path

    If the ball turns 1 complete rotation (360°), it will travel pi*diameter units.

    So to cover the path it needs curve_length / pi*diameter of full rotations.

    The catch is that driver expects the input in radians, not degrees. So a full rotation of 360° is 2*pi radians.

    (2pi) * curve_length / pidiameter, we can simplify and remove pi

    The last thing is the minus in front of the expression (-), this is to influence which direction we want the ball to roll. You can use the right hand rule to see what rotation is positive, and what negative (thumb in axis direction, fingers point in positive rotation direction).

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

enter image description here

$\endgroup$
4
  • 3
    $\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, 2014 at 4:26
  • 3
    $\begingroup$ This video is a good start to drivers. $\endgroup$
    – sambler
    Dec 26, 2014 at 8:50
  • $\begingroup$ Pinging Jaroslav towards the question below... $\endgroup$
    – aliasguru
    Jun 16, 2020 at 7:59
  • $\begingroup$ Hi @ThomasKordi, I included info how I got that expression $\endgroup$ Jun 17, 2020 at 2:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .