[Closed] lookat script for only one axis
I’ve searched the forum already and found posts that get me close to what I need but not exactly. I’m frantically trying to understand matrix maths so I can get this done. Object1 is parented to Object2 and Object1 I need to lookat Object3, but only on the Z axis. People will say to assign a lookat controller and switch off inherit rotation. But I can’t do that cause I need Object1 to move and rotate with it’s parent(Object2), but just have it’s Z axis rotate so that it is still aligned to Object2 in all axis’ except it’s Z.
This is a transform script controller assigned to Object1 that I pilfered from a post here that gets me almost there.
obj2 = $Object2
obj3 = $Object3
theY = tar.pos - par.pos
theY.z = 0.0
theY = normalize theY
theX = cross theY [0,0,1]
TM = matrix3 1
TM.row1 = theX
TM.row2 = theY
TM.row4 = [0,0,0]
TM
This all works until I rotate Object2 out of world alignment, which I absolutely need to do for this rig.
here is a solution that doesn’t require any scripting or math at all:
- create a point helper P and align it to your Object1.
- link P to Object2.
- move P in local x axis a bit.
- add a lookat controller to Object1 and set P as the lookat target, make sure x is the lookat axis.
- change the upnode type to lookat and set Object3 as the upnode object, make sure the upnode axis is z.
Hope this is what you were looking for.
Thanks for replying guys, but the lookat controller isn’t an option. There is no way to get a lookat controller to only rotate on a single axis. Even with an upnode, there’s always 2 axis of rotation to get an object to look at another object. I mustn’t have explained myself very well if 2 people are giving me similar answers. This is for a car rig… For the automated steering. The object3 is a point that averages the position of object2 over 1 frame in the past and 2 frames in the future to help smooth out it’s motion. Sometimes, like when a car is starting to go up a hill, Object3 is out of the same plane of object2 and then object1 will be rotating on more than just the Z axis. So I really do need a script solution for this.
Actually, looking more closely at your answer jonahhawk, I realise that it isn’t using the lookat controller, however this solution doesn’t work either cause the looking object isn’t in world space co-ordinates and spins all over the place as the parent moves and rotates around.
Use a lookAt constraint on object A.
Parent A to B.
Add a Expose Transform Helper to the scene and expose the transforms for A.
Now wire the axis of the object that you want to have only rotate on one axis to the exposed local axis in the EXTM node.
Hi Paul, very much appreciate the reply. That’s definitely the closest and most useful solution thus far. But it’s not 100% there. The rotation stays in the plane that it’s supposed to and that’s the main thing so the geom for the brakes don’t move around inaccurately, but the rotation is not totally accurate to be able to point the object at the lookat target totally accurately. I’ve linked a file demonstrating this. If you view through the camera, you’ll see the yellow plane (which is linked to the object that is having it’s Z rotation driven by the expose tranform) isn’t always exactly lined up with the centre of the lookat target (orange point) Some of the frames where it’s most apparent are 14,20,26,32,47,53,58,64,75,82,90.
http://home.iprimus.com.au/wickergray/LookatSingleAxis04Path04.max
But like I said, this gets me closer than I’ve got with any other methods and I’m going to use this method. So a massive thanks for that. Although I am still in search of a matrix maths perfect solution if anyone can point me in the right direction. Back to watching Bobo’s dvd “the matrix explained” on the weekend to see if I can get anything more to stick in my brain and make sense.
Cheers,
Cg.
Ill have a look in a bit at the file. Solving it with a matrix solution is really quite easy. You need to find the three vectors for row 1 through 3 of the matrix, row 4 is the position. You are doing the right DVD, Bobo did a fantastic job of that one.
We will assume the is looking along the X axis with this example and that we have two objects, $lookFrom and $lookAt and the result is being either applied to $lookFrom or another object in the same location.
This is off the top of my head.
X=normalize ($lookAt.pos-$lookFrom.pos)
Z=[0,0,0]--predetermined up vector to start with.
Y=normalize (cross Z X)--Get the Y vector
X=normalize (cross Y Z)--Recalculate the X so that it isn't directly looking at the target
(matrix3 X Y Z $lookFrom.pos)
in real life the steering is more complected thing but for a start my snippet has to help:
(
local body, look, target
fn updateCarWheels = with undo off
(
tm = translate (body.transform.rotation as matrix3) look.pos
v = normalize (target.pos*(inverse tm))
ang = atan (v.y/v.x)
ang += if v.x < 0 then 90 else -90
look.transform = prerotateZ tm ang
)
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]
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
orient = Orientation_Constraint local_world:1
orient.appendTarget look 100
w1.rotation.controller = w2.rotation.controller = orient
)
target = dummy name:"LookAt_Target" boxsize:[4,4,4] pos:[0,100,0]
when transform #(body, target) change id:#car_system handleAt:#redrawViews do updateCarWheels()
body
)
)
move the car or the target to see how constraints work.
I suggest to forget about LookAt controller and use Rotation Script or Transform Script. (I would prefer the Transform Script Controller) .