Tuesday, April 21, 2009

Rolling wheel

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.

1 comment:

Anonymous said...

very interesting script, thanks for sharing ;]