Rigging a Rolling Sphere (BB-8)

Euler rotations are not suitable for this, an Euler XYZ rotation is only going to work if you move your sphere along X followed by Y, not the other way around…

yes as you can see from my example… LOL!

I am taking each change in position, and calculate the cross product with a vector straight up, to get the vector perpendicular to these two,

I kinda sorta remember that Cross Products had something to do with finding Normals… but I honestly don’t remember the details of them… I am googling them now… (Keep in mind I’m not a spring chicken… I’m the ripe old age of 57 and not getting any younger so this may take me awhile…

Have mercy on me is what I’m sayin… LOL!

calculate the angle the wheel needs to turn, in radians. From axis and angle I create a Quaternion rotation,

this part I understand… Quaternions being derived from Radians in the first place… (or at least I think I understand)

This script is great, i needed something to roll a ball around and this is the only script i have found that works even if the ball is scaled down! the only other script i found used 2 blender units for a complete rotation so worked well with default spheres but as soon as you made it small it looked really bad, so thanks for this!

awesome! that’s just what I wanted
I edited the code a little bit, so that it accepts bones for more complex rigs


######################################
######################################
##########     Made By    ############
##########    eezacque    ############
######################################
######################################


import bpy
import bpy.app


from mathutils import Vector 
from mathutils import Quaternion


# Initialize 
previous=Vector((0,0,0))
rotation = Quaternion((1,0,0,0))
# the name of the armature
armature = 'Armature'
# the name of the bone that is moving the sphere
controller = 'Main'
# the name of the sphere
ball = 'Sphere'




def foobar(n):
    global previous
    global rotation
    current=bpy.data.objects[armature].pose.bones[controller].location.copy()
    diameter=bpy.data.objects[ball].dimensions[0]
    delta=current-previous
    previous=current
    
    distance=delta.length
    delta.normalize()
    up = Vector((0, 0, 1))
    axis = -delta.cross(up)
    angle=distance/diameter*2
    rotation.rotate(Quaternion(axis,angle))
    
    if n==0: return rotation.w
    elif n==1: return rotation.x
    elif n==2: return rotation.y
    elif n==3: return rotation.z






# Register function for driver use   
bpy.app.driver_namespace['foobar'] = foobar

wow thanks for the effort on this @ehabcharek

I’ve been taking some online python coarses to get better at using python…
this inspires me to work on my python skill more…

Here’s a version that is specific to the object being driven (no need for script per ball).
See roller_local.blend for an example.