walking on walls -- alignToVec

Posted By: JibbSmart

walking on walls -- alignToVec - 09/28/09 03:55

G'day!

A while back when my old "quaternions" were getting a little more attention I had some requests for examples of how they could be used to rotate an object to align to a wall so that it can walk on whatever surface it wants, no matter what the angle is. I helped a couple of people with it, and have seen another request for such a function, so I thought people might appreciate it.

This does not require my quaternion code. I personally prefer to use my quaternions (albeit a much more updated version than my previous contribution, which will get updated when the next public beta comes out), but this function here has been designed for use with normal A7 Euler angles (pan, tilt and roll).

This is a (very slightly modified) function I wrote for Pappenheimer which other people might like:
Code:
function alignToVec(ANGLE* entAng, VECTOR* vec, VECTOR* axis, var factor) {
	vec_rotate(axis, entAng);
	vec_normalize(axis, 1);
	vec_normalize(vec, 1);
	VECTOR rotAxis;
	vec_cross(rotAxis, vec, axis);
	var angle = -acos((float)vec_dot(axis, vec)) * factor * vec_length(rotAxis);
	ANGLE rotAngle;
	ang_for_axis(rotAngle, rotAxis, angle);
	ang_add(entAng, rotAngle);
}


entAng is the angle that gets modified. This will commonly be "my.pan", but if you're using c_rotate you won't use this function to modify "my.pan" directly.

vec is the vector (in world space) that the angle should get lined-up with (this will commonly be "normal" after doing a c_trace or c_move).

axis is the vector (in local space, relative to the angle) that needs to get aligned to "vec" (for walking on walls, this will commonly be "vector(0, 0, 1)", which is straight up relative to the angle).

factor usually ranges from 0-1 (but there's nothing stopping you from using any other value), and indicates how far to rotate the angle (where 1 = complete alignment, and 0 = no rotation).

TWO IMPORTANT NOTES:

1.
The alignment has been "smoothed out" to prevent stuttering/shaking due to var's finite precision, so calling "alignToVec" with a factor of "1" just once often won't be a complete alignment (it'll get most of the way there). Call "alignToVec(........, 1)" once every frame over several frames to complete the alignment (this will be quite smooth and quite quick), or several times in one frame for a complete alignment in only one frame.

If you would rather deal with the imprecisions yourself, remove the "* vec_length(rotAxis);". If you call "alignToVec" with a factor of 1 every frame you will often come across a stuttering or shaking.

2.
This requires the latest public beta (A7.8), but also relies on a bug in the latest beta. "ang_for_axis" currently uses radians instead of degrees. Apparently this has been fixed and will be solved in the next public release, and so this will require this:
Code:
-acos((float)vec_dot(axis, vec))

to be changed to this:
Code:
-acosv(vec_dot(axis, vec))

when the update comes out.

I hope you find this useful!

Jibb
Posted By: Saturnus

Re: walking on walls -- alignToVec - 09/28/09 07:04

This is in fact a really handy function, thank you!

The only drawback is, that it can't be used in the free version of lite-C (full version too?) as lite-C wasn't updated since several months. But I guess this could be solved by using your quaternion code?
Posted By: JibbSmart

Re: walking on walls -- alignToVec - 09/28/09 08:12

Cheers.

It could be solved by my quaternion code, but the main change I want to make to my quaternion code is that it uses ang_for_axis to convert back to a Euler angle (which is the reason 7.8 is needed here), instead of its current method (which isn't smooth when it approaches certain orientations). I would solve that by converting the quaternion to a matrix and rotating the entity with that, but the functions to modify an entity's orientation using matrices also require 7.8. Sorry.

Hopefully Lite-C will be updated with the next update. Feel free to give my quaternions a go anyway, as the conversion back to Euler angles should be precise enough for most situations (a few years ago I had physics that used my quaternion code and that went pretty smoothly).

Jibb
Posted By: Alan

Re: walking on walls -- alignToVec - 09/28/09 21:38

Hi,

very nice function and I would really like to use it, but I do not entirely understand what the "axis" parameter is supposed to be. Where do I obtain it from? ("vec" is clear, it's the normal of the surface, "entAng" is clear as well and "factor" is always 1 for my purpose) Could you please explain it to me once more, maybe going a little more into detail? Basically, all I want to do is having the feet of my model face the ground below them at any time, no matter what it looks like.
I already asked that question in the other thread but I assume the chances are higher that you see it in here, besides it is part of this topic anyway wink
Posted By: JibbSmart

Re: walking on walls -- alignToVec - 09/28/09 22:07

G'day grin I've already answered in your topic, but I'll answer here for the benefit of others.

Basically, when you have an angle and a vector to line it up with, you need to decide how you'll line it up -- vec_to_angle, for example, lines up the angle's local x with the vector that's given to it. To do the same thing with my function, you'd pass it "vector(1, 0, 0)" -- except my function won't set roll to zero, as it makes the smallest rotation possible to line up the axis and the vector.

For most situations (such as walking on walls) you want to line up the entity's "up" with the surface normal. "vector(0, 0, 1)" points straight up, so that's what you'll pass to the function, along with "normal".

I hope I've made this clear now.

Jibb
Posted By: Gumby22don

Re: walking on walls -- alignToVec - 09/28/09 23:07

Nice contribution - when's the next Alien v Predator game being made in A7? tongue

Don
have a great day
Posted By: Alan

Re: walking on walls -- alignToVec - 09/29/09 13:03

@JulzMighty: I've just implemented your code into my project - and it is just AMAZING! Works perfect! Thanks a lot for contributing!


Greets,


Alan
Posted By: Alan

Re: walking on walls -- alignToVec - 09/29/09 14:35

Hi,

it's me again xD
Well, your code works really good when using level-blocks (as you can see on the picture I've added to this post), but whenever I want to walk around on a model (like the half-pipe on the picture), there is no rotation at all (second picture). Do you have any idea how this is possible?

Greets,


Alan


Attached picture screen_block.jpg
Attached picture screen_model.jpg
Posted By: sebbi91

Re: walking on walls -- alignToVec - 09/29/09 15:50

hey cool, sonic ^^
Posted By: Alan

Re: walking on walls -- alignToVec - 09/29/09 16:31

Hi,

I've been able to fix it. It wasn't the fault of your code, just a stupid mistake of mine... *stands up to make another cup of coffee* sorry for that.


Greets,


Alan
Posted By: JibbSmart

Re: walking on walls -- alignToVec - 09/30/09 10:18

Hi Alan!

I'm glad you were able to resolve the issue before I got a chance to see the question grin But still if there are any questions, don't hesitate.

Thanks everyone for the support laugh

Jibb
Posted By: GnR

Re: walking on walls -- alignToVec - 12/23/10 04:26

Do you have a code example of using this with c_rotate? I am already using c_rotate to adjust the pan on my model and I am trying to use your function to align my model with a slope in the same frame. I'm sure it's simple enough but I'm not getting it.
Posted By: JibbSmart

Re: walking on walls -- alignToVec - 12/23/10 19:43

I believe it's something like:
Code:
ANGLE tempAng;
vec_set(tempAng, my.pan);
alignToVec(tempAng, normal, vector(0, 0, 1), 1);
vec_sub(tempAng, my.pan);
c_rotate(me, tempAng, GLIDE);


c_rotate adds the rotation to the entity's current orientation, so if we want to align it with an angle, all we need to do is subtract its real orientation first, and then perform the c_rotate with the difference (as shown above).

I don't have time to test it, since I'm about to go on holiday for Christmas with my family laugh

Jibb
Posted By: Tobias

Re: walking on walls -- alignToVec - 12/23/10 20:13

I believe you need the parameter USE_AXIS for c_rotate. c_rotate(....,USE_AXIS) is the same as ang_add, only with collision detection.
Posted By: GnR

Re: walking on walls -- alignToVec - 12/26/10 05:15

Thank you for the quick answer and example.

And yes USE_AXIS is definitely required in the c_rotate. Appreciate your help.
© 2024 lite-C Forums