Ok, I admit this has been discussed to death on any 3d forum. There are different techniques depending on projects baseline, but I'll present here one that combines a scripted controller with custom attribute.
At
PEN's site you'll find info on using attributes with scripted controllers.
First create a custom attribute definition where to store rot script variables
def = attributes wheelCtrl
(
local dist=0
local lastTime=0
)
Create a control circle
myCircle = circle name:"Master" radius:30
custAttributes.add myCircle def
Create a cylinder
myCyl = cylinder radius:30 height:10 name:"Wheel"
rotate myCyl (eulerAngles 90 0 0)
move myCyl [0,0,30]
myCyl.parent = myCircle
Apply a script controller to the y rotation of the wheel
myRotCtrl = myCyl.rotation.y_rotation.controller=float_script()
myRotCtrl.addNode "master" myCircle
And the script goes here:
myRotCtrl.script = "
if F==0 then
(
master.wheelCtrl.dist = 0
master.wheelCtrl.lastTime = 0
)
--The old and the current pos
p0 = at time (master.wheelCtrl.lastTime) master.pos
p1 = master.pos
--Get the distance traveled
newDist = distance p0 p1
--The direction of the wheel travelling
multi = dot master.transform.row1 (normalize (p1-p0))
--Calculate the rotation and add it to CA var
master.wheelCtrl.dist += multi * newDist / (master.radius)
--Set the last frame to current frame
master.wheelCtrl.lastTime = F
--apply result
master.wheelCtrl.dist
"
Here's
file (R2009) to see it in action.