# direction I need direction on direction

Please take a moment to consider if this thread is worth bumping.

## Recommended Posts

Posted (edited)

Hi! I am decent at scripting, but have a blind spot the size of Jupiter when it comes to rotations.  I have a scenario where I have a flat prim on the ground (basically an invisible doormat), where a collision triggers a bit of chat to the agent. No biggie.

However, I need it to respond differently depending on whether an avatar is moving in line with or contrary to the prim's local "forward" axis (x-axis in my test prim). After some testing, I figured I could theoretically do this with the rotation difference between the prim and the avatar. Depending on the global quadrant the prim is facing (and the direction the avatar is facing when walking), this is (in vectors) either  <0.0, 0.0, 0.0> or <180,  0, 0>. This would basically cover scenarios 1 and 2 below where you move forward with W, with the camera position behind you.

Trick is that it's also possible to move "backwards", by which I mean pressing the S, to that your avatar is facing the camera. (I'm leaving aside, for the moment, that an avatar can cross left-to-right or right-to-left as well)

I also get the feeling that my lack of trigonometry skill is causing me to over-complicate things. Can someone point me in the right direction (pun totally intended) on how I can get this to work robustly?

I attached an image detailing my four scenarios.

Edited by Bugs Larnia
Spelling
##### Share on other sites

Velocity has both a direction and a magnitude, so perhaps llDetectedVel might be useful here.

##### Share on other sites
Posted (edited)
38 minutes ago, KT Kingsley said:

Velocity has both a direction and a magnitude, so perhaps llDetectedVel might be useful here.

True, it is. I suspect it's a function of prim rotation vs. avatar rotation, combined with avatar velocity. I am just uncertain how the three factors play with each other.

Edited by Bugs Larnia
##### Share on other sites

Here's my link to my comment which has a link to my comment:

It's about doors, but it absolutely applies here too.

• 2
##### Share on other sites
30 minutes ago, Wulfie Reanimator said:

Here's my link to my comment which has a link to my comment:

It's about doors, but it absolutely applies here too.

I don't know why it works, but it works! I do often get a double triggering of collision_start, with the second one directly contradicting the first, but I can work around that with a list of recent collision keys.

Thanks Wulfie!

Sample code triggering the double collision follows here

```default
{
collision_start(integer piNum)
{
vector vAvatarDirection = llVecNorm(llDetectedPos(0) - llGetPos()) / llGetRot();
if (vAvatarDirection.y < 0)
{
llOwnerSay("Moving forward");
}
else
{
llOwnerSay("Moving backward");
}
}
}```

##### Share on other sites
Posted (edited)
34 minutes ago, Bugs Larnia said:

I don't know why it works, but it works!

The first part (llDetectedPos(0) - llGetPos()) calculates a vector (direction + distance), and the second part (divide by llGetRot()) basically "removes" the object's rotation from that vector. It rotates the vector counter to the object's own rotation. This effectively cancels any rotation, meaning that the vector's X-component will match the world's X-component. (Same with Y and Z.)

Once we have a vector that's aligned with the world (or "global space"), we can easily check for things like front/back, left/right, or up/down, since they're directly correlated with X, Y, and Z.

One way of problem-solving I would always recommend is having your object at ZERO_ROTATION so you don't have to worry about relative rotations at all. If you're able to solve it like that, it's usually just a tiny tweak with (* llGetRot) or (/ llGetRot) to solve the problem in any rotation.

Edited by Wulfie Reanimator
• 2
• 1
##### Share on other sites

Funnily enough I was just working on a similar problem. I used detected velocity instead of a position differential.

```    collision_start(integer n)
{
vector vel = llList2Vector(llGetObjectDetails(llDetectedKey(0),[OBJECT_VELOCITY]),0);
vel = vel/llGetRot();
if(vel.y<0)
llSay(0,"Wrong Way!");
else
llSay(0,"Right Way!");
}```

My object also was llVolumeDetect(TRUE), which may or may not affect things for your application.

• 1
##### Share on other sites
1 hour ago, Quistessa said:

Funnily enough I was just working on a similar problem. I used detected velocity instead of a position differential.

```
collision_start(integer n)
{
vector vel = llList2Vector(llGetObjectDetails(llDetectedKey(0),[OBJECT_VELOCITY]),0);
vel = vel/llGetRot();
if(vel.y<0)
llSay(0,"Wrong Way!");
else
llSay(0,"Right Way!");
}```

My object also was llVolumeDetect(TRUE), which may or may not affect things for your application.

Thanks! I thought about using phantom and volume detection, but it wasn't really necessary for this setup.

##### Share on other sites
5 hours ago, Bugs Larnia said:

phantom and volume detection,

If you ever do, I'm fairly certain you want to use one or the other and not both.

• 1
##### Share on other sites
18 hours ago, Quistessa said:

If you ever do, I'm fairly certain you want to use one or the other and not both.

Well, you can use both, but it's not strictly necessary. I was more referring to the status of the prim, which is influenced by the settings of llVolumeDetect, but your point is well taken.

• 1
##### Share on other sites

Please take a moment to consider if this thread is worth bumping.