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