[Closed] lookat script for only one axis
Cheers Paul for the reply. I might be doing something wrong or different to you cause I can’t get your coded solution to work.
Dennis, that looks like exactly what I need. I’ll see if I can turn that into a transform script.
When you say steering is a bit more complicated than just pointing 2 wheels at a future position, were you talking about the Ackermann angle? If so, I’m going to solve this in the auto steering by adding a lookat for each wheel seperately. And with the manual control switch I’m going to figure how to implement a proper Ackermann-type control.
Thanks to all that replied, I’ve learned a lot from you and really appreciate it.
Cg.
Yes. the Ackermann angle is the first thing. The second is the roll center, and the third is the castor angle. But the most important thing is that wheels never look at a destination point, they follow the radius of turning circle.
The Castor Angle visually doesn’t make a big difference, and I would neglect this value.
I wasn’t able to load the original .max file (wrong version?) but here is a remix of Denis’ code tweaked into a rotation_script.
The wheels stay aligned even if the car is tumbling which I think is what you are after.
with undo off
(
delete objects
fn makeWheel name: pos: wirecolor: =
(
w = cylinder name:name sides:24 segments:1 radius:5 height:3 pos:pos wirecolor:wirecolor
w.objectOffsetRot = eulerangles 0 90 0
CenterObject w
w
)
body = box name:"Car_Body" width:20 length:40 height:5 pos:[0,0,11] isselected:on wirecolor:blue
body.pivot = [0,0,0]
local w1,w2,w3,w4
in body
(
w1 = makeWheel name:"LF_weel" pos:[-10,15,5] wirecolor:orange
w2 = makeWheel name:"RF_weel" pos:[10,15,5] wirecolor:orange
w3 = makeWheel name:"LB_weel" pos:[-10,-15,5] wirecolor:brown
w4 = makeWheel name:"RB_weel" pos:[10,-15,5] wirecolor:brown
look = point name:"Dir_Dummy" size:10 axistripod:on box:on pos:[0,15,5] wirecolor:yellow
target = dummy name:"LookAt_Target" boxsize:[4,4,4] pos:[0,100,0]
)
orient_script = rotation_script()
orient_script.AddNode "lookAt" $LookAt_Target
orient_script.AddNode "lookFrom" $Dir_Dummy
orient_script.AddNode "referenceFrame" $Car_Body
orient_script.SetExpression (
"v = (lookAt.position - lookFrom.position) * (inverse referenceFrame.Transform)
" +
"ang = atan(v.y/v.x)
" +
"ang += if v.x < 0 then 90 else -90
" +
"((rotateZMatrix ang) as quat)
"
)
w1.rotation.controller = w2.rotation.controller = orient_script
body
)
)
here is a little tweaked version of biddle:
with undo off
(
delete objects
fn makeWheel name: pos: wirecolor: =
(
w = cylinder name:name sides:24 segments:1 radius:5 height:3 pos:pos wirecolor:wirecolor
w.objectOffsetRot = eulerangles 0 90 0
CenterObject w
w
)
local body, look, target
body = box name:"Car_Body" width:20 length:40 height:5 pos:[0,0,11] isselected:on wirecolor:blue
body.pivot = [0,0,0]
local w1,w2,w3,w4
in body
(
w1 = makeWheel name:"LF_weel" pos:[-10,15,5] wirecolor:orange
w2 = makeWheel name:"RF_weel" pos:[10,15,5] wirecolor:orange
w3 = makeWheel name:"LB_weel" pos:[-10,-15,5] wirecolor:brown
w4 = makeWheel name:"RB_weel" pos:[10,-15,5] wirecolor:brown
look = point name:"Dir_Dummy" size:10 axistripod:on box:on pos:[0,15,5] wirecolor:yellow
)
-- it shouldn't be a child of the car body
target = dummy name:"LookAt_Target" boxsize:[4,4,4] pos:[0,100,0]
orient_script = rotation_script()
orient_script.AddNode "lookAt" target
orient_script.AddNode "lookFrom" look
orient_script.AddNode "referenceFrame" body
orient_script.SetExpression (
"v = lookAt.pos*(inverse (translate (referenceFrame.transform.rotation as matrix3) lookFrom.pos))
" +
"ang = atan (v.y/v.x)
" +
"ang += if v.x < 0 then 90 else -90
" +
"((rotateZMatrix ang) as quat)
"
)
w1.rotation.controller = w2.rotation.controller = orient_script
body
)