LookAt and Terrain normals

Anybody know of a way to turn a node towards another while respecting terrain normals?

char.node.lookAt(target)
char.node.setPos(char.node, 0, char.speed * dt, 0)
normal = terrain.getSurfaceNormal(char.node.getX(), char.node.getY())
fwd = render.getRelativePoint(char.node, (0,1,0))
char.node.headsUp(fwd, normal)

The lookAt command will rotate towards a target, but it seems then rotating the char based on the slope of the terrain then means they are no longer looking at the target…if that makes sense :smiley:

I’ve tried only changing the heading, and then rotating based on normal, but that also seems wrong?

I’m not entirely clear on what you’re trying to do, especially as you seem to be using two different versions of “lookAt” (one being “headsUp”) one shortly after the other. Do you want the node to point towards the target? To point towards the target, but with a preference for keeping “up” in the direction of the surface normal? To turn towards the target, but never pointing “into” terrain? Something else that I’m missing? You say that you want to “turn a node towards another while respecting terrain normals”, but I’m honestly unclear on what that means. ^^;

Hehe - sorry, wasn’t sure if I was making sense :slight_smile:

^ This

Would I need to ditch the lookAt maybe and somehow adjust the fwd vector instead?

Aaah, I see now, I believe.

Hmm… Have you tried just using “headsUp” (without “lookAt”)? Something like this:

# Note, no use of "lookAt"
char.node.setPos(char.node, 0, char.speed * dt, 0)
normal = terrain.getSurfaceNormal(char.node.getX(), char.node.getY())
# NB:
char.node.headsUp(target, normal)

If that doesn’t work, I think that you might be able to do it by first zeroing the node’s H, P and R, then setting its pitch to the vertical angle of the normal, and then finally setting its heading, relative to itself, to the horizontal angle between the line from the node to its target and the y-axis; something like this:

normal = <get normal, as per usual>
vertAngle = <calculate angle> # This should be achievable with a bit of trigonometry

#  I'm not sure of whether it's feasible to do these two
# steps as one; it might be.
char.node.setHpr(0, 0, 0)
char.node.setP(vertAngle)

diff = target.getPos() - char.node.getPos()
diff2D = Vec2(diff.x, diff.y)
horiAngle = diff2D.signedAngleDeg(Vec2(0, 1))
char.node.setH(char.node, horiAngle)